Spring底层AOP代码实现


一. AOP功能测试


①. pom.xml 依赖导入


②. 目标类


③. 切面类


④. 配置类


⑤. 测试类


二. AOP原理-@EnableAspectJAutoProxy【开启切面自动化代理】

AOP原理:【看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?】@EnableAspectJAutoProxy;
  		
  1、@EnableAspectJAutoProxy是什么?
  		@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar组件
  			利用AspectJAutoProxyRegistrar将internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator后置处理器的BeanDefinetion的定义信息添加到BeanDefinitionRegistry中
  			       只是注册定义信息并没创建AnnotationAwareAspectJAutoProxyCreator对象
                                    例如,RootBeanDefinition beanDefinition = new RootBeanDefinition(AnnotationAwareAspectJAutoProxyCreator);
                                         registry.registerBeanDefinition("internalAutoProxyCreator", beanDefinition);
  2、 AnnotationAwareAspectJAutoProxyCreator的类结构信息:
  		AnnotationAwareAspectJAutoProxyCreator
  			->AspectJAwareAdvisorAutoProxyCreator
  				->AbstractAdvisorAutoProxyCreator
  					->AbstractAutoProxyCreator
  							implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
  						现在我们关注这两个接口: AnnotationAwareAspectJAutoProxyCreator是后置处理器,另外一个怎么装配BeanFactory

  AbstractAutoProxyCreator.setBeanFactory()
  AbstractAutoProxyCreator.有后置处理器的逻辑;

  AbstractAdvisorAutoProxyCreator.setBeanFactory()-》initBeanFactory()

  AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()


①. 给容器中导入AspectJAutoProxyRegistrar


②. 利用AspectJAutoProxyRegistrar自定义类给容器注册名为AnnotationAwareAspectJAutoProxyCreator的bean组件,BeanDefinetion


③. 给容器中注册一个AnnotationAwareAspectJAutoProxyCreator的bean组件


④. AnnotationAwareAspectJAutoProxyCreator继承关系


⑤. 关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactory;因为①至③步骤只是注册了组件并没有创建AnnotationAwareAspectJAutoProxyCreator对象


a、AbstractAutoProxyCreator.setBeanFactory()


b、AbstractAutoProxyCreator.有后置处理器的逻辑


c、AbstractAdvisorAutoProxyCreator.setBeanFactory()-》initBeanFactory()


d、AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()


三. 创建和注册AnnotationAwareAspectJAutoProxyCreator组件的bean对象的过程

流程:
    1)传入配置类,创建IOC容器
    2)注册配置类,调用refresh();方法刷新容器
    3)如何刷新:
       registerBeanPostProcessors(beanFactory);
       注册bean的后置处理器来方便拦截bean的创建
    registerBeanPostProcessors方法里面调用registerBeanPostProcessors
    registerBeanPostProcessors里面步骤:
      1.获取IOC容器已经定义好的需要创建对象的所有的BeanPostProcessor
          比如: 该@EnableAspectJAutoProxy注解只是将AnnotationAwareAspectJAutoProxyCreator后置处理器的BeanDefinition定义信息添加到BeanDefinitionRegistry中,但是还没创建其对应的对象
            
        对应的代码:String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
      2.给容器添加一些别的BeanPostProcessor
        对应代码:beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
      3.优先将实现了PriorityOrdered接口的BeanPostProcessor创建并注册到容器中 registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors)
      4.将实现了Ordered接口的BeanPostProcessor创建并注册到容器中registerBeanPostProcessors(beanFactory, orderedPostProcessors);
      5.最后将没实现优先级接口的BeanPostProcessor创建并注册到容器中 registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors)
        3-5步的原码解释:
              // Separate between BeanPostProcessors that implement PriorityOrdered,
              // Ordered, and the rest.
               
              // First, register the BeanPostProcessors that implement PriorityOrdered. 
              // Next, register the BeanPostProcessors that implement Ordered. 例子 AnnotationAwareAspectJAutoProxyCreator实现了 Ordered
              // Now, register all regular BeanPostProcessors.
      6.怎么创建和注册呢? 
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class)--> doGetBean -->getSingleton(beanName,singletonFactory)-->this.singletonFactory.getObject() 
        ---> 跳到createBean(beanName, mbd, args);创建对象-->doCreateBean(beanName, mbdToUse, args)
        
          例如,创建internalAutoProxyCreator的后置处理器,其实类型是AnnotationAwareAspectJAutoProxyCreator
          创建bean的过程:
           1 创建Bean实例
           2 populateBean:给bean的各种属性赋值
	   3 initializeBean:初始化bean:
              过程:
                1.invokeAwareMethods(),处理Aware接口的方法回调
					private void invokeAwareMethods(final String beanName, final Object bean) {
						if (bean instanceof Aware) {
							if (bean instanceof BeanNameAware) {
								((BeanNameAware) bean).setBeanName(beanName);
							}
							if (bean instanceof BeanClassLoaderAware) {
								((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
							}
							if (bean instanceof BeanFactoryAware) {
								((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
							}
						}
					} // 该步骤会执行AbstractAdvisorAutoProxyCreator#setBeanFactory方法,自动装配BeanFactory
                2.applyBeanPostProcessorsBeforeInitialization():后置处理器的PostProcessorsBeforeInitialization方法
                3.invokeInitMethods():执行自定义的初始化方法
                4.applyBeanPostProcessorsAfterInitialization():后置处理器的PostProcessorsAfterInitialization方法
          4 BeanPostProcessor(以AnnotationAwareAspectJAutoProxyCreator为例的bean)创建成功
      7.把BeanPostProcessor注册到beanFactory中:
                orderedPostProcessors.add(pp);
                registerBeanPostProcessors(beanFactory, orderedPostProcessors);
	     执行PostProcessorRegistrationDelegate#registerBeanPostProcessors方法,调用 beanFactory.addBeanPostProcessor(postProcessor)---> this.beanPostProcessors.add(beanPostProcessor);
  =========上面就是创建和注册AnnotationAwareAspectJAutoProxyCreator组件的bean全过程===========
            AnnotationAwareAspectJAutoProxyCreator ========>InstantiationAwareBeanPostProcessor


①. 注册配置类,调用refresh()刷新容器


②. registerBeanPostProcessors(beanFactory),创建并注册bean的后置处理器来方便拦截bean的创建


③. 先获取ioc容器已经存在定义信息,但需要创建BeanPostProcessor后置处理器的对象


④. 将实现了Ordered接口的BeanPostProcessor,将其创建并注册到容器中registerBeanPostProcessors(beanFactory, orderedPostProcessors)


⑤. 创建internalAutoProxyCreator的后置处理器,类型是AnnotationAwareAspectJAutoProxyCreator的BeanPostProcessor

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class) --> doGetBean --> getSingleton-->singletonFactory.getObject()

--- > 跳到createBean(beanName, mbd, args)---> 创建对象-->doCreateBean(beanName, mbdToUse, args)


⑥. populateBean:属性赋值与其它bean的依赖注入


7. initializeBean:初始化操作


8. invokeAwareMethods():处理Aware接口的方法回调,自动装配BeanFactory

该步骤会执行AbstractAdvisorAutoProxyCreator#setBeanFactory方法,自动装配BeanFactory

private void invokeAwareMethods(final String beanName, final Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		if (bean instanceof BeanClassLoaderAware) {
			((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
		}
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

把beanFactory设置到BeanPostProcessor的setBeanFactory方法中

AnnotationAwareAspectJAutoProxyCreator#initBeanFactory,创建aspectJAdvisorFactory 和 aspectJAdvisorsBuilder对象


9. applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) --> 后置处理器的 beanProcessor.postProcessBeforeInitialization(result, beanName)方法


10. invokeInitMethods(beanName, wrappedBean, mbd),执行自定义的初始化方法


11. applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) -->后置处理器的 beanProcessor.postProcessAfterInitialization(result, beanName)


12. 将BeanPostProcessor后置处理器对象创建完成后注册到beanPostProcessors中

1、registerBeanPostProcessors(beanFactory, orderedPostProcessors);

2、执行PostProcessorRegistrationDelegate#registerBeanPostProcessors方法,调用 beanFactory.addBeanPostProcessor(postProcessor);

private static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
	for (BeanPostProcessor postProcessor : postProcessors) {
		beanFactory.addBeanPostProcessor(postProcessor);
	}
}

3、this.beanPostProcessors.add(beanPostProcessor);


四. 业务bean和切面bean对象的创建

finishBeanFactoryInitialization(beanFactory);完成BeanFactory的初始化工作,就是创建剩下的单实例bean
        1.遍历获取容器中所有的Bean,依次创建对象getBean(beanName);
            getBean(beanName);->doGetBean()->getSingleton()->singletonFactory.getObject();->createBean
        2.注意第一步的createBean,它是有if条件的
          首先是从缓存中获取当前bean,如果能获取到证明bean是之前被创建过的,直接使用
          如果获取不到进入else语句,创建bean
          这样就保证单实例的bean只会被创建一次,创建好的bean会被缓存起来
        3.createBean() 创建bean
          [AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截,
          因为它是InstantiationAwareBeanPostProcessor类,会调用postProcessBeforeInstantiation()方法]
          AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean的实例
          [BeanPostProcessor是在bean对象创建完成初始化前后调用的]
          [InstantiationAwareBeanPostProcessor是在创建Bean实例之前,判断容器是否已经存在bean实例,若存在,则尝试使用用后置处理器为其创建一个代理对象]
                这样的bean实例一般是通过以下方式创建的:
                    @EnableAspectJAutoProxy
                    @Configuration
                    public class MainConfigOfAOP {
                    	 
                    	//业务逻辑类加入容器中
                    	@Bean
                    	public MathCalculator calculator(){
                    		return new MathCalculator();
                    	}

                    	//切面类加入到容器中
                    	@Bean
                    	public LogAspects logAspects(){
                    		return new LogAspects();
                    	}
                }

			若容器已存在bean实例,则通过 AbstractAutowireCapableBeanFactory#createBean --> resolveBeforeInstantiation(beanName, mbdToUse) 尝试使用用后置处理器为其创建一个代理对象;
                    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                    解析resolveBeforeInstantiation(beanName, mbdToUse);
					希望后置处理器在此返回一个代理对象,如果能返回就使用,如果不能就第二步


	4.若容器不存在bean实例,执行 doCreateBean(beanName, mbdToUse, args);这个是真正创建bean

				 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
              		    throws BeanCreationException {

          		  	    // 创建 bean 实例
            			instanceWrapper = createBeanInstance(beanName, mbd, args);
            			
            			// bean 属性的填充
            			populateBean(beanName, mbd, instanceWrapper);
            			
            			// bean 初始化过程
            			exposedObject = initializeBean(beanName, exposedObject, mbd);
                }

                protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {

	                    // 处理Aware接口的方法回调
                    	invokeAwareMethods(beanName, bean);

                    	// 后置处理器前置方法
                    	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
                    	
                    	// 自定义的初始化方法
                    	invokeInitMethods(beanName, wrappedBean, mbd);
                    	
                    	// 后置处理器后置方法
                    	wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
                }

第一次是bean实例已经存在,Object bean = resolveBeforeInstantiation(beanName, mbdToUse)

第二次bean实例不存在,创建完实例,在bean初始化之后尝试为其生成代理对象


第一次、bean实例已经存在,会走到 Object bean = resolveBeforeInstantiation(beanName, mbdToUse)方法,使用后置处理器尝试为bean目标方法生成代理类


五. 若容器中目标对象bean已经存在,


会走到 Object bean = resolveBeforeInstantiation(beanName, mbdToUse)方法


则后置处理AnnotationAwareAspectJAutoProxyCreator尝试调用postProcessBeforeInstantiation()方法尝试为目标对象bean创建proxy代理对象

AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用:

A、bean实例已经存在,调用 postProcessBeforeInstantiation();

			 关心MathCalculator和LogAspect的创建

  		1、判断当前bean是否在advisedBeans中,若为true,则为不代理

  		2、判断isInfrastructureClass方法检查Bean的类是否是Spring AOP的基础设施类,比如是否实现了特定的接口(如Advice、Pointcut等),或者是否是切面(@Aspect)

  		3、是否需要跳过

  			a、获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】
  				       每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor;
  				       判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true
  			b、永远返回false


①. 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean


②. 判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true


六. 若容器中目标对象bean不存在,


bean实例创建完,在bean的初始化过程中,执行AbstractAutowireCapableBeanFactory#initializeBean方法--->applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),


则 AnnotationAwareAspectJAutoProxyCreator后置处理尝试调用 postProcessAfterInitialization()尝试为bean创建proxy代理对象

创建对象
B、postProcessAfterInitialization;return wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下

  		1、获取当前bean的所有增强器(通知方法)  Object[]  specificInterceptors
  			a、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
  			b、获取到能在bean使用的增强器。
  			c、给增强器排序

  		2、保存当前bean在advisedBeans中;

  		3、如果当前bean需要增强,创建当前bean的代理对象;
  			a、获取所有增强器(通知方法)
  			b、保存到proxyFactory
  			c、创建代理对象:Spring自动决定
  				JdkDynamicAopProxy(config);jdk动态代理;
  				ObjenesisCglibAopProxy(config);cglib的动态代理;

  		4、给容器中返回当前组件使用cglib增强了的代理对象;

  		5、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;


第二次,在bean的初始化过程中wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)也会提供使用后置处理器生成代理类


①. wrapIfNecessary()


②. 获取当前bean的所有增强器(通知方法) Object[] specificInterceptors


③. 保存当前bean在advisedBeans中


④. 如果当前bean需要增强,创建当前bean的代理对象


⑤. 给容器中返回当前组件使用cglib增强了的代理对象


⑥. 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程


七. 目标方法执行

目标方法执行;容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);
  		1、CglibAopProxy.intercept();拦截目标方法的执行
  		2、根据ProxyFactory对象获取将要执行的目标方法拦截器链;
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  			a、List<Object> interceptorList保存所有拦截器 5
  				一个默认的ExposeInvocationInterceptor 和 4个增强器;
  			b、遍历所有的增强器,将其转为Interceptor;
  				registry.getInterceptors(advisor);
  			c、将增强器转为List<MethodInterceptor>;
  				如果是MethodInterceptor,直接加入到集合中
  				如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
  				转换完成返回MethodInterceptor数组;
  
  		3、如果没有拦截器链,直接执行目标方法;
  			拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
  		4、如果有拦截器链,把需要执行的目标对象,目标方法,
				拦截器链等信息传入创建一个 CglibMethodInvocation 对象,
				并调用 Object retVal =  mi.proceed();
 		5、拦截器链的触发过程;
  			a、如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
  			b、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
  				拦截器链的机制,保证通知方法与目标方法的执行顺序;


①. 容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx)


②. CglibAopProxy.intercept();拦截目标方法的执行


③. 根据ProxyFactory对象获取将要执行的目标方法拦截器链


④. 如果没有拦截器链,直接执行目标方法


⑤. 如果有拦截器链,把需要执行的目标对象,目标方法


⑥. 拦截器链的触发过程


八. 目标方法执行


九. AOP-原理总结

总结:
	1、 @EnableAspectJAutoProxy 开启AOP功能
	2、 @EnableAspectJAutoProxy 通过 @Import会将 AnnotationAwareAspectJAutoProxyCreator后置处理器的Bean定义信息【BeanDefinition】注册到Spring容器中
	3、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
	4、容器的创建流程:
		(1)、registerBeanPostProcessors()创建bean的后置处理器对象; AnnotationAwareAspectJAutoProxyCreator 后置处理器对象的创建
		(2)、finishBeanFactoryInitialization()初始化剩下的单实例bean
			a、创建业务逻辑组件和切面组件过程中
			b、若容器中的bean已存在,则使用 AnnotationAwareAspectJAutoProxyCreator后置处理器尝试拦截bean组件为其创建一个proxy代理对象
			c、若容器中的bean不已存在,组件创建完之后,再次使用AnnotationAwareAspectJAutoProxyCreator后置处理器尝试拦截bean组件为其创建一个proxy代理对象
					判断组件是否需要增强
						是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个proxy代理对象,可能是cglib,也可能是jdk;
				
						
	5、执行目标方法:
		(1)、代理对象执行目标方法
		(2)、CglibAopProxy.intercept();
			a、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
			b、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
			c、效果:
				正常执行:前置通知-》目标方法-》返回通知-》后置通知
				出现异常:前置通知-》目标方法-》异常通知-》后置通知
posted @ 2024-08-23 21:14  jock_javaEE  阅读(33)  评论(0)    收藏  举报