动态代理模式(spring默认JDK动态代理模式)
jdk动态代理模式(有接口的目标对象)
- 如何产生代理对象
Object proxy =
Proxy.newProxyInstance(classloader,interfaces,InvocationHandler);
classloader —作用是加载jdk帮我们写出来的代理类的字节码 interfaces — 目标类的接口数组
InvocationHandler — 接口、自己写实现类
- 产生代理对象的底层原理
由JDK编写代理类的源文件(.java)-----interfaces,InvocationHandler
由JDK编译成class文件
使用传入的classloader加载class文件—ClassLoader - 如何执行代理对象
InvocationHandler.invoke(proxy , Method , args){
before();
//调用目标对象的目标方法
Method.invoke(target,args);
after();
}
//proxy ---代理对象本身
//Method --- 原对象的方法对象
//args --- Method方法的参数
cglib动态代理模式(没有接口和非final的目标对象)—ASM(生成和修改字节码的工具包)
- 如何产生代理对象
Enhancer enhancer = new Enhancer();
enhancer.setSuperClass(目标对象的class对象);
enhancer.setCallback(MethodInterceptor的实现类);
Object proxy = enhancer.create();
- 产生代理对象的底层原理
使用ASM工具包去针对目标类的class文件,进行修改,产生新的class文件 - 如何执行代理对象
MethodInterceptor的实现类.intercept(proxy , targetMethod , args , proxyMethod){
before();
//调用目标对象的目标方法
//Method.invoke(target,args);
methodProxy.invokeSuper(proxy, arg);
after();
}
详解产生代理对象的流程及相关核心类的作用
spring aop产生代理对象的流程的入口
执行时机:发生在ioc三步创建流程中的第三步初始化之后去触发aop流程
- AspectJAwareAdvisorAutoProxyCreator接口继承体系:
AspectJAwareAdvisorAutoProxyCreator接口继承体系:
|-BeanPostProcessor
postProcessBeforeInitialization---初始化之前调用
postProcessAfterInitialization---初始化之后调用
|--InstantiationAwareBeanPostProcessor
postProcessBeforeInstantiation---实例化之前调用
postProcessAfterInstantiation---实例化之后调用
postProcessPropertyValues---后置处理属性值
|---SmartInstantiationAwareBeanPostProcessor
predictBeanType
determineCandidateConstructors
getEarlyBeanReference
|----AbstractAutoProxyCreator
postProcessBeforeInitialization
postProcessAfterInitialization----AOP功能入口
postProcessBeforeInstantiation
postProcessAfterInstantiation
postProcessPropertyValues
...
|-----AbstractAdvisorAutoProxyCreator
getAdvicesAndAdvisorsForBean
findEligibleAdvisors
findCandidateAdvisors
findAdvisorsThatCanApply
|------AspectJAwareAdvisorAutoProxyCreator
extendAdvisors
sortAdvisors
aop流程入口:
AbstractAutoProxyCreator#postProcessAfterInitialization
核心类:
AbstractAutoProxyCreator:负责创建代理对象的创建器
- ProxyFactory:代理对象工厂
- ProxyCreatorSupport:产生AopProxy的工厂类
- AopProxy(重点):真正的代理对象产生的工厂、它本身还是InvocationHandler接口的实现类
- JdkDynamicAopProxy:产生jdk代理对象的
- Object proxy(代理对象)= Proxy.newProxyInstance(classloader,interfaces,InvocationHandler);
- ObjenesisCglibAopProxy:产生cglib代理对象的
- Object proxy = enhancer.create();
- JdkDynamicAopProxy:产生jdk代理对象的
- AopProxy(重点):真正的代理对象产生的工厂、它本身还是InvocationHandler接口的实现类
- ProxyCreatorSupport:产生AopProxy的工厂类
思考:
什么时候产生代理对象?
- ioc容器创建bean的时候,会触发aop,产生代理对象,放入aop
什么时候调用代理对象
- 当第一次调用目标类接口的实例的时候,才是第一次去调用代理对象
有没有可能产生了代理对象,却没有调用过
- 可能
详解执行流程及相关核心类的作用
源码入口:JdkDynamicAopProxy#invoke方法
重要代码分析:
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- chain集合中存储的是【Advice类】封装之后的【MethodInterceptor】或者想要的Adapter
- 在该代码执行之前,我们已经针对该targetClass获取到了对应的【Advisor集合】,最终想要的是【MethodInterceptor集合】
- 代码思路:Advisor—>getAdvice—>获取MethodInterceptor(三个通知可以强转,两个通知需要适配)
- Advice继承体系
Advisor和Advice的关系
- 一个Advisor(PointcutAdvisor)是封装了一个Advice(五种通知),同时还封装了对应的Pointcut对象(AspectJExpressionPointcut)
Advice和MethodInterceptor的关系是什么?
-
Advice接口是MethodInterceptor的父接口
-
Advice有五个实现类,也就是五种通知,但是只有三种通知是实现MethodInterceptor接口
- AspectJAfterAdvice
- AspectJAroundAdvice
- AspectJAfterThrowingAdvice)
-
Advice另外的两个通知,要想和MethodInterceptor建立关系,需要使用适配器模式
-
AfterReturnningAdviceAdapter:【AspectJAfterReturnningAdvice----->MethodInterceptor】
-
MethodBeforeAdviceAdapter:【AspectJMethodBeforeAdviceAdvice----->MethodInterceptor】
-
ThrowsAdviceAdapter:【AspectJThrowsAdviceAdvice----MethodInterceptor】----没有被用到
-
Advice为什么要封装成MethodInterceptor?
- MethodInterceptor提供了一个接口功能叫intercept,使用此方法完成对执行方法的拦截,方便执行增强功能。
- MethodInterceptor相当于针对五种通知有五个实现类,每个实现类都需要去完成方法拦截和【方法顺序的控制】。
一个目标对象可以被多个增强功能去增强,最终只会产生一个代理对象。
- 多个增强功能的执行顺序是如何保证的呢?
- 【不同通知类型】的执行顺序是通过MethodInterceptor实现类去保证的。
- 【同种同种类型】的执行顺序是通过对advice的加载顺序(xml顺序或者注解处理的顺序)去保证的。
ReflectiveMethodInvocation的解析:
- 由它完成MethodInterceptor拦截到的方法是应该如何一个一个的执行
- 编写流水线执行流程
- 它将Advice封装成一个调用链
invoke方法就是调用被增强类的方法
事务源码阅读
- 入口:TxAdviceBeanDefinitionParser#doParse方法