12.21 Spring AOP
本章内容
什么是
SpringAOP?为什么使用
SpringAOP
AOP术语
什么是SpringAOP?
AOP全称Aspect Oriented Programming面向切面编程。和OOP一样,是一种编程思想
AOP的特点:
-
采用动态代理机制取代传统的继承机制。减少重复性代码
-
分离功能性需求和非功能性需求,增强代码的可读性和可维护性
保证开发者在不修改源代码的前提下,为系统中的业务组件添加通用功能。AOP就是代理模式的典型应用
目前最流行的AOP框架
Spring AOP,它有两种实现方式
基于接口的
JDK动态代理基于继承的
CGLB动态代理
AspectJ
Spring JDK动态代理
实现方法:
实现InvocationHandler接口,重写invoke方法,客户端使用Java.lang.reflect.Proxy类产生动态代理类的对象。
代码实现:
agency包:
package com.web.agency;
/**
* @description:aop切面的两个增强方法
* @data: 2021/12/21 14:55
* @author: Lucifer
*/
public class MyAspect {
public void myBefore(){
System.out.println("方法执行前!");
}
public void myAfter(){
System.out.println("方法执行后!");
}
}
dynamic包:
package com.web.dynamic;
import com.web.agency.MyAspect;
import com.web.service.UserManager;
import com.web.service.impl.UserManagerImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @description:aop的动态代理类,实现invocationHandler接口
* @data: 2021/12/21 15:03
* @author: Lucifer
*/
public class JdkProxy implements InvocationHandler {
private Object target; // 需要代理的目标对象
final MyAspect myAspect = new MyAspect();
/* 重写拦截方法 */
service包:
package com.web.service;
/**
* @description:spring的aop练习,位于service层
* @data: 2021/12/21 14:48
* @author: Lucifer
*/
public interface UserManager {
/* CURD操作 */
// 新增用户
void addUser(String userName, String password);
// 删除用户
void delUser(String userName);
}
service.impl包:
package com.web.service.impl;
import com.web.service.UserManager;
/**
* @description:spring的aop练习,位于service层接口的实现类
* @data: 2021/12/21 14:49
* @author: Lucifer
*/
public class UserManagerImpl implements UserManager {
Spring CGLIB动态代理
特点:
不需要实现接口(Spring核心包当中已经集成了CGLIB所需要的包)
具体实现:(其他的地方大致和上面的JDK动态代理一致,下面只记有区别的类)
package com.web.dynamic;
import com.web.agency.MyAspect;
import com.web.service.UserManager;
import com.web.service.impl.UserManagerImpl;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @description:aop的另外一种代理方式:cglib
* @description:实现methodinterceptor接口位于cglib包下
* @data: 2021/12/21 16:51
* @author: Lucifer
*/
public class CglibProxy implements MethodInterceptor {
private Object target; // 需要代理的目标
final MyAspect myAspect = new MyAspect();
// 重写拦截方法
两个动态代理的区别
JDK动态代理特点
-
代理对象必须实现一个或多个接口
-
以接口的形式接收代理实例,而不是代理类
CGLIB动态代理特点
-
代理对象不能被 final 修饰
-
以类或接口形式接收代理实例
JDK与CGLIB动态代理的性能比较
生成代理实例性能:JDK > CGLIB 代理实例运行性能:JDK > CGLIB
特点:
-
JDK 动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用 InvokeHandler 来处理。
-
CGLIB 动态代理是利用 ASM 开源包,加载代理对象类的 class 文件,通过修改其字节码生成子类来处理。
-
JDK 动态代理只能对实现了接口的类生成代理,而不能针对类。
-
CGLIB 是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。因为是继承,所以该类或方法不能声明成 final 类型。
为什么使用AOP
AOP的好处:
-
提供了一种可插入的方式,可在实现逻辑之前、之后、周围添加其他关注点
举例:
class A{
public void m1(){...}
public void m2(){...}
public void m3(){...}
public void m4(){...}
public void m5(){...}
public void n1(){...}
public void n2(){...}
public void p1(){...}
public void p2(){...}
public void p3(){...}
}
如果需要不同字母开头的方法执行传统的做法:分别修改方法的内容
如果使用AOP,则不用在方法内调用发送通知的方法,只需要在类的方法中定义切入点,然后在XML文件中调用。如果需要删除或修改此功能,那么只需要在XML文件中进行更改。使用AOP可以增强代码的可维护性。--->个人理解其作用是改变这种继承调用的方式。同时减少代码量
AOP术语
这些术语适用于其他AOP框架:
| 名称 | 说明 |
|---|---|
| Joinpoint(连接点) | 指那些被拦截到的点,在 Spring 中,指可以被动态代理拦截目标类的方法。 |
| Pointcut(切入点) | 指要对哪些 Joinpoint 进行拦截,即被拦截的连接点。 |
| Advice(通知) | 指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容。 |
| Target(目标) | 指代理的目标对象。 |
| Weaving(植入) | 指把增强代码应用到目标上,生成代理对象的过程。 |
| Proxy(代理) | 指生成的代理对象。 |
| Aspect(切面) | 切入点和通知的结合。 |
增强处理:
| 通知 | 说明 |
|---|---|
| before(前置通知) | 通知方法在目标方法调用之前执行 |
| after(后置通知) | 通知方法在目标方法返回或异常后调用 |
| after-returning(返回后通知) | 通知方法会在目标方法返回后调用 |
| after-throwing(抛出异常通知) | 通知方法会在目标方法抛出异常后调用 |
| around(环绕通知) | 通知方法会将目标方法封装起来 |
AOP的好处:
-
AOP是Spring的核心之一,在Spring中经常会使用AOP来简化编程。 -
提供声明式企业服务,服务是声明式事务管理。
-
允许用户实现自定义切面。在某些不适合用
OOP编程的场景中,采用AOP来补充。 -
可以对业务逻辑的各个部分进行隔离,使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,提高开发效率。
-

浙公网安备 33010602011771号