spring AOP
一、基本概念
- 切入点(pointcut):在哪些类、哪些方法上切入。
- 通知(advice):在方法执行的什么时候做什么。
- 切面(aspect):切入点+通知,在什么时机,什么地方,做何种增强。
- 织入(weave):把切面加入到对象,并创建出代理对象的过程。
二、原理
<aop:aspectj-autoproxy />
proxy-target-class属性,默认为false,使用jdk动态代理:JdkDynamicAopProxy
proxy-target-class属性 设置为true 或者 类是非接口的,使用cgLib:ObjenesisCglibAopProxy
2.1、生成代理对象
spring aop是通过BeanPostProcessor实现的,初始化bean后,会调用 BeanPostProcessor 的 applyBeanPostProcessorsAfterInitialization方法
aspecj的BeanPostProcessor为: AnnotationAwareAspectJAutoProxyCreator
AbstractAutoProxyCreator#postProcessAfterInitialization
DefaultAopProxyFactory#createAopProxy
- 判断是否创建代理以及使用哪个代理:AbstractAutoProxyCreator#wrapIfNecessary
生成List
AbstractAutoProxyCreator#postProcessBeforeInstantiation,实例化(doCreateBean)之前,即 postProcessBeforeInitialization 之前
打了Aspect注解的bean
打了Pointcut 注解 的方法不生成advisor,但会根据 Pointcut 值 来判断是否创建代理对象
打了Before, Around, After, AfterReturning, AfterThrowing 注解的方法会生成advisor
其中interfaces 包含
原被代理类接口class
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
org.springframework.core.DecoratingProxy
2.1.1 jdk动态代理
使用方式
- Proxy.newProxyInstance
传参
ClassLoader loader Class<?>[] interfaces InvocationHandler h
生成的代理对象
调用 Proxy.newProxyInstance
代理类对象
命名:com.sun.proxy.$Proxy + num(计数值)
类关系:实现了interfaces,继承Proxy
通过拼接字节码生成新的类,生成的新的类
java.lang.reflect.Proxy.ProxyClassFactory#apply
* sun.misc.ProxyGenerator#generateProxyClass(java.lang.String, java.lang.Class<?>[], int)
生成的代理类对象实现了interfaces 的方法,内部实际是调用InvocationHandler对象的invoke方法
逻辑概述
代理类:实现了interfaces,继承Proxy
代理类对象:实现了interfaces方法,内部调用InvocationHandler对象的invoke方法
- toString、hashcode、equals等Object方法也会调invocationHandler.invoke(…)
2.2、方法执行
执行invoke
获取该方法的拦截器(advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass))
创建 ReflectiveMethodInvocation
执行reflectiveMethodInvocation#proceed
- 依次调用advice 拦截器方法