Spring(4.1)Spring aop 动态代理----代理对象的产生和执行流程

动态代理模式(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方法的参数

Spring(4.1)Spring aop 动态代理----代理对象的产生和执行流程_第1张图片

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();

思考:

什么时候产生代理对象?

  • 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继承体系
    Spring(4.1)Spring aop 动态代理----代理对象的产生和执行流程_第2张图片

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方法

你可能感兴趣的:(#,SSM框架)