欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring AOP源码解析

程序员文章站 2022-07-12 14:58:24
...


前言

本文主要介绍Spring AOP原理


AOP底层原理

1、@EnableAspectJAutoProxy

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;
    boolean exposeProxy() default false;
}

@Import({AspectJAutoProxyRegistrar.class})给容器中导入AspectJAutoProxyRegistrar类,这个类实现了ImportBeanDefinitionRegistrar接口,可以添加自定义组件。

在AspectJAutoProxyRegistrar里核心的地方是

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
Spring AOP源码解析

这个AOP的工具类主要作用是把AnnotationAwareAspectJAutoProxyCreator这个类的BeanDefinition信息注册到spring容器中。

    @Nullable
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, 
    BeanDefinitionRegistry registry, @Nullable Object source) {
       Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
         //如果已经存在了自动代理创建器
        if (registry.containsBeanDefinition(
           "org.springframework.aop.config.internalAutoProxyCreator")) 
            BeanDefinition apcDefinition = 
                 registry.getBeanDefinition(                       
                 "org.springframework.aop.config.internalAutoProxyCreator");
            //存在的自动代理创建器与现在的不一致,那么需要根据优先级来判断需要使用哪个
            if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                int currentPriority = 
                    findPriorityForClass(apcDefinition.getBeanClassName());
                int requiredPriority = findPriorityForClass(cls);
                if (currentPriority < requiredPriority) {
                    //改变bean最重要的就是改变bean所对应的className属性
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }
           //如果已经存在自动代理创建器并且与将要创建的一致,那么无需再次创建
            return null;
        } else {
            //生成BeanDefinition信息
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); 
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", -2147483648);
            beanDefinition.setRole(2);  
            //加类定义信息注册到Spring容器
            registry.registerBeanDefinition(
                "org.springframework.aop.config.internalAutoProxyCreator", beanDefinition); 
            return beanDefinition;
        }
    }

2、AspectJAwareAdvisorAutoProxyCreator

Spring AOP源码解析

从类图可以了解到AspectJAwareAdvisorAutoProxyCreator这个类的功能。

实现了一系列Aware的接口,在Bean装载的时候获取BeanFactory(Bean工厂),Bean的ClassLoader,还实现了Order接口,继承了ProxyConfig,ProxyConfig中主要封装了代理的通用处理逻辑,比如选择JDK动态代理或者CGLIB代理。

JDK动态代理:其代理对象必须是某个接口的实现,它通过在运行期间创建一个接口的实现类来完成对目标对象的代理。

CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象时针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM操作字节码实现的,性能比JDK强。

能够让这个类参与到Bean初始化过程,是由于这个类实现了BeanPostProcessor接口(后置处理器)。

3、AOP流程

3.1、容器创建

  1. 传入配置类,创建IOC容器
  2. 注册配置类
  3. 调用refresh方法刷新容器
public class TestAop {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new 
        AnnotationConfigApplicationContext(MainConfigAop.class);
        MathCalculator mathCalculator = context.getBean(MathCalculator.class);
        System.out.println(mathCalculator.dev(2, 1));
        context.close();
    }
}
 public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        this();
        this.register(componentClasses);
        this.refresh();
    }

3.2、注册后置处理器

使用registerBeanPostProcessors(beanFactory)注册Bean的后置处理器,来拦截Bean的创建

  1. 先获取IOC容器中已经定义了并且需要创建对象的BeanPostProcessor

    Spring AOP源码解析
  2. 给容器中添加其他后置处理器

     beanFactory.addBeanPostProcessor
     (new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(         
     beanFactory,beanProcessorTargetCount));
    
  3. 优先创建实现PriorityOrdered接口的BeanPostProcessor对象。添加到beanFactory中。

  4. 再创建实现Ordered接口的BeanPostProcessor对象。添加到beanFactory中。

  5. 之后创建没有实现Ordered接口的BeanPostProcessor对象。添加到beanFactory中。

  6. 给容器中添加其他后置处理器

    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    

创建BeanPostProcessor对象过程

​ 以创建internalAutoProxyCreator的BeanPostProcessor为例。

Spring AOP源码解析
  1. 在doCreateBean中,首先创建Bean的实例

    instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    
  2. 给属性赋值

    this.populateBean(beanName, mbd, instanceWrapper);
    
  3. 初始化Bean

    exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    
    • 初始化Aware接口的方法回调 例如设置BeanFactory

      this.invokeAwareMethods(beanName, bean);
      //看bean是否实现XXXAware接口,如果有实现就设置相应值
      private void invokeAwareMethods(String beanName, Object bean) {
              if (bean instanceof Aware) {
                  if (bean instanceof BeanNameAware) {
                      ((BeanNameAware)bean).setBeanName(beanName);
                  }
      
                  if (bean instanceof BeanClassLoaderAware) {
                      ClassLoader bcl = this.getBeanClassLoader();
                      if (bcl != null) {
                          ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
                      }
                  }
      
                  if (bean instanceof BeanFactoryAware) {
                      ((BeanFactoryAware)bean).setBeanFactory(this);
                  }
              }
      
          }
      
    • 执行后置处理器的postProcessBeforeInitialization方法

      wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
      
    • 执行自定义初始化方法

      this.invokeInitMethods(beanName, wrappedBean, mbd);
      
    • 执行后置处理器的postProcessAfterInitialization方法

      wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
      
  4. 到此为止,AnnotationAwareAspectJAutoProxyCreator类型的BeanPostProcessor对象创建成功。

  5. 注册到beanFactory中

     registerBeanPostProcessors(beanFactory, xxxPostProcessors)
     
     private static void registerBeanPostProcessors(ConfigurableListableBeanFactory 
         beanFactory, List<BeanPostProcessor> postProcessors) {
            Iterator var2 = postProcessors.iterator();
            while(var2.hasNext()) {
                BeanPostProcessor postProcessor = (BeanPostProcessor)var2.next();
                //添加到beanFactory中
                beanFactory.addBeanPostProcessor(postProcessor);
            }
        }   
    

3.3、初始化剩下的单实例Bean

完成BeanFactory的初始化工作

finishBeanFactoryInitialization(beanFactory);
  1. 遍历获取容器中所有得Bean,依次创建对象。经历过程 getBean->doGetBean->getSingleton

  2. 创建Bean(业务逻辑组件和切面组件)

    • 先从缓存中获取当前Bean,如果能获取到,说明Bean是之前创建过的,直接使用,否则需创建。(只要创建好的Bean都会被缓存起来,这是Spring保证单实例Bean的实现原理

      先从缓存中检查有没有这个 Bean
      // Eagerly check singleton cache for manually registered singletons.
      Object sharedInstance = getSingleton(beanName);
      
      如果等于null,才会继续执行下面的方法
      sharedInstance = getSingleton(beanName, () -> {
        try {
               return this.createBean(beanName, mbd, args);
           } catch (BeansException var5) {
               this.destroySingleton(beanName);
               throw var5;
           }
        });
      
    • createBean 创建Bean。AnnotationAwareAspectJAutoProxyCreator会在Bean创建之前先尝试返回Bean的实例。

      BeanPostProcessor:是对象创建Bean完成进行初始化前后调用的。

      InstantiationAwareBeanPostProcessor:是创建Bean实例之前先尝试用后置处理器返回对象。

      • 实例化:指创建类实例(对象)的过程。比如使用构造方法new对象,为对象在内存中分配空间。(要创建对象,但是并未生成对象)
      • 初始化:指为类中各个类成员(被static修饰的成员变量)赋初始值的过程,是类生命周期中的一个阶段。简单理解为对象中的属性赋值的过程。(对象已经生成,为其属性赋值)
      1. 解析BeforeInstantiation,希望后置处理器在此能返回一个代理对象,如果能返回就使用该对象;不能返回就继续执行创建。

        beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
        
         @Nullable
         protected Object resolveBeforeInstantiation(String beanName, 
         RootBeanDefinition mbd) {
             Object bean = null;
             if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
               if (!mbd.isSynthetic() && 
                this.hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = this.determineTargetType(beanName, mbd);
                if (targetType != null) {
                 //InstantiationAwareBeanPostProcessor 类型的后处理器进行 
                 //postProcessBeforelnstantiation 方法
                bean = 
                this.applyBeanPostProcessorsBeforeInstantiation(targetType,beanName);
                     if (bean != null) {
                      //如果实例已经存在
                     //BeanPostProcessor类型的postProcessAfterlnitialization方法的调用。
                     bean =  
                     this.applyBeanPostProcessorsAfterInitialization(bean,beanName);
                            }
                        }
                    }
                    mbd.beforeInstantiationResolved = bean != null;
                }
                return bean;
            }   
        
      2. 真正的去创建一个Bean,和之前3.2.6的流程是一样的。

        beanInstance = this.doCreateBean(beanName, mbdToUse, args);
        

      AnnotationAwareAspectJAutoProxyCreator 会在任何 Bean 创建完成之前先尝试返回 Bean 的实例,因为它实现了 InstantiationAwareBeanPostProcessor 接口,这个接口有两个方法,一个postProcessBeforeInstantiation,另一个postProcessAfterInstantiation,这两个方法是在 Bean 创建完成前后执行的,而 BeanPostProcessor 接口的两个方法是在创建完成并且初始化前后调用的。

      1. 在每一个Bean创建之前调用applyBeanPostProcessorsBeforeInstantiation方法中会拿到所有后置处理器,判断如果是InstantiationAwareBeanPostProcessor类型的,就执行postProcessBeforeInstantiation方法。

        if (bp instanceof InstantiationAwareBeanPostProcessor) {
        InstantiationAwareBeanPostProcessor ibp = 
            (InstantiationAwareBeanPostProcessor)bp;
        Object result = ibp.postProcessBeforeInstantiation(beanClass,beanName);
        

        ​ 在postProcessBeforeInstantiation方法中

        1. 判断当前Bean是否在advisedBeans(保存了所有需要增强的bean)中

        2. 判断当前Bean是否是基础类型Advice、PointCut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)

        3. 判断是否该跳过

          • 获取候选的增强器(切面里面的通知方法)每一个封装的通知方法的增强器是InstantiationModelAwarePointcutAdvisor

            Spring AOP源码解析

          • 判断每一个增强器是否是AspectJPointcutAdvisor类型的,如果是就返回true,不是就返回false。

           protected boolean shouldSkip(Class<?> beanClass, String beanName) {
                  List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
                  Iterator var4 = candidateAdvisors.iterator();
                  Advisor advisor;
                  do {
                      if (!var4.hasNext()) {
                          return super.shouldSkip(beanClass, beanName);
                      }
                      advisor = (Advisor)var4.next();
                  } while(!(advisor instanceof AspectJPointcutAdvisor) || !((AspectJPointcutAdvisor)advisor).getAspectName().equals(beanName));
                  return true;
              }
          

        InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法在

        populateBean中触发。该方法仍然处于实例化过程

        populateBean(beanName, mbd, instanceWrapper);//触发     postProcessAfterInstantiation方法
        
      2. 在 Bean 初始化之后调用 BeanPostProcessorpostProcessAfterInitialization 方法。增强需要增强的Bean。

        @Override
        public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        	if (bean != null) {
                //根据给定的bean的class和name构建这个key,格式:beanClassName_beanName
        		Object cacheKey = getCacheKey(bean.getClass(), beanName);
        		if (!this.earlyProxyReferences.contains(cacheKey)) {
                    //如果它适合被代理,则需要封装指定bean
        			return wrapIfNecessary(bean, beanName, cacheKey);
        		}
        	}
        	return bean;
        }
        
        1. wrapIfNecessary方法中,获取当前Bean的所有增强器(通知方法),判断是否需要包装(增强)。

           Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
          
          @Nullable
          protected Object[] getAdvicesAndAdvisorsForBean(
          		Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
          	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
          	if (advisors.isEmpty()) {
          		return DO_NOT_PROXY;
          	}
          	return advisors.toArray();
          }
          
          

          如何找到增强器呢?

          protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
          	List<Advisor> candidateAdvisors = findCandidateAdvisors();
          	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
          	extendAdvisors(eligibleAdvisors);
          	if (!eligibleAdvisors.isEmpty()) {
          		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
          	}
          	return eligibleAdvisors;
          }
          
          

          获取所有的增强以及寻找所有增强中适用于bean的增强并应用。

        2. 保存当前bean到advisedBeans

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

           Object proxy = this.createProxy(bean.getClass(), beanName,  specificInterceptors, new SingletonTargetSource(bean));
          
          • 获取所有的增强器(通知方法)

          • 保存到proxyFactory

            protected Object createProxy(
            			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
            		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
            		}
                    // 1.创建proxyFactory,proxy的生产主要就是在proxyFactory做的
            		ProxyFactory proxyFactory = new ProxyFactory();
            		proxyFactory.copyFrom(this);
             
            		if (!proxyFactory.isProxyTargetClass()) {
            			if (shouldProxyTargetClass(beanClass, beanName)) {
            				proxyFactory.setProxyTargetClass(true);
            			}
            			else {
            				evaluateProxyInterfaces(beanClass, proxyFactory);
            			}
            		}
             
                    // 2.将当前bean适合的advice,重新封装下,封装为Advisor类,然后添加到ProxyFactory中
            		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
            		for (Advisor advisor : advisors) {
            			proxyFactory.addAdvisor(advisor);
            		}
             
            		proxyFactory.setTargetSource(targetSource);
            		customizeProxyFactory(proxyFactory);
             
            		proxyFactory.setFrozen(this.freezeProxy);
            		if (advisorsPreFiltered()) {
            			proxyFactory.setPreFiltered(true);
            		}
             
                    // 3.调用getProxy获取bean对应的proxy
            		return proxyFactory.getProxy(getProxyClassLoader());
            	}
            
          • 创建代理对象,spring自动决定使用哪种动态代理

             // getProxy()方法
            	public Object getProxy(ClassLoader classLoader) {
            		return createAopProxy().getProxy(classLoader);
            	}
                // createAopProxy()方法就是决定究竟创建何种类型的proxy
            	protected final synchronized AopProxy createAopProxy() {
            		if (!this.active) {
            			activate();
            		}
                    // 关键方法createAopProxy()
            		return getAopProxyFactory().createAopProxy(this);
            	}
             
                // createAopProxy()
            	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
                    // 1.config.isOptimize()是否使用优化的代理策略,目前使用与CGLIB
                    // config.isProxyTargetClass() 是否目标类本身被代理而不是目标类的接口
                    // hasNoUserSuppliedProxyInterfaces()是否存在代理接口
            		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            			Class<?> targetClass = config.getTargetClass();
            			if (targetClass == null) {
            				throw new AopConfigException("TargetSource cannot determine target class: " +
            						"Either an interface or a target is required for proxy creation.");
            			}
                        
                        // 2.如果目标类是接口或者是代理类,则直接使用JDKproxy
            			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            				return new JdkDynamicAopProxy(config);
            			}
                        
                        // 3.其他情况则使用CGLIBproxy
            			return new ObjenesisCglibAopProxy(config);
            		}
            		else {
            			return new JdkDynamicAopProxy(config);
            		}
            	}
            
            Spring AOP源码解析
          1. 给容器中返回当前组件使用cglib增强了的代理对象
          2. 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程。

3.4、目标方法的执行

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

  1. org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptorintercept方法拦截目标方法的执行。

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

    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    

    拦截器链如何获取?

    主要是在getInterceptorsAndDynamicInterceptionAdvice方法中。

    1. 创建一个集合保存所有的拦截器

       List<Object> interceptorList = new ArrayList(advisors.length);
      

      一个默认的org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR和四个增强器。

      Spring AOP源码解析
    2. 遍历所有的增强器,将其转为Interceptor

      Advisor[] var9 = advisors;
      int var10 = advisors.length;
      for(int var11 = 0; var11 < var10; ++var11) {
          Advisor advisor = var9[var11];
             registry.getInterceptors(advisor);
      
    3. 将增强器转为List

      • 如果本来就是MethodInterceptor,则直接加到集合中

      • 如果不是,则使用AdvisorAdapter 适配器转为 MethodInterceptor

        @Override
        public MethodInterceptor getInterceptor(Advisor advisor) {
        	AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
        	return new AfterReturningAdviceInterceptor(advice);
        }
        
        
      • 转化完成返回MethodInterceptor数组

    4. 拦截器链(每一个方法又被包装为方法拦截器,利用MethodInterceptor机制控制执行顺序)

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

    retVal = methodProxy.invoke(target, argsToUse);
    
  4. 如果有拦截器链,把需要执行的目标对象、目标方法、拦截器链等信息传入创建一个CglibMethodInvocation对象,并调用proceed()方法

    retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, 
                                  targetClass, chain, methodProxy)).proceed();
    
  5. 拦截器链的触发过程,触发方法就是proceed

       @Nullable
        public Object proceed() throws Throwable {
            //如果没有拦截器或者已经到最后一个拦截器,就执行目标方法
            if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
                return this.invokeJoinpoint();
            } else {
               //到下一个拦截器执行
                Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
                if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                    InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
                    Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
                    return dm.methodMatcher.matches(this.method, targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
                } else {
                    return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
                }
            }
        }
    
    1. 如果没有拦截器或者是最后一个拦截器就执行目标方法

       if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
                  return this.invokeJoinpoint();
              }
      
    2. 如果有拦截器就链式的获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行。

      这里的返回值是还是拦截器,传入的是这个拦截器本身,每次调用都会减少一个长度,并且改变当前的拦截器,
      所以执行顺序是栈式的结构。
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
      
      1. 首先执行ExposeInvocationInterceptor拦截器的invoke方法

        public Object invoke(MethodInvocation mi) throws Throwable {
            MethodInvocation oldInvocation = (MethodInvocation)invocation.get();
            invocation.set(mi);
        
            Object var3;
            try {
                var3 = mi.proceed();
            } finally {
                invocation.set(oldInvocation);
            }
        
            return var3;
        }
        

        代码的核心业务是放在finally中的,肯定会执行。下面接着进入proceed方法中。

      2. 再执行AspectJAfterThrowingAdvice拦截器的invoke方法

        public Object invoke(MethodInvocation mi) throws Throwable {
            try {
                return mi.proceed();
            } catch (Throwable var3) {
                if (this.shouldInvokeOnThrowing(var3)) {
                    this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, var3);
                }
        
                throw var3;
            }
        }
        

        注意到这里有异常的捕捉,异常发生是在这里处理的,没有异常则不会执行,继续proceed方法。

      3. 再执行AfterReturningAdviceInterceptor拦截器的invoke方法

        @Override
        public Object invoke(MethodInvocation mi) throws Throwable {
        	Object retVal = mi.proceed();
        	this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        	return retVal;
        }
        
        

        继续执行proceed方法

      4. 再执行AspectJAfterAdvice拦截器的invoke方法

        @Override
        public Object invoke(MethodInvocation mi) throws Throwable {
        	try {
        		return mi.proceed();
        	}
        	finally {
        		invokeAdviceMethod(getJoinPointMatch(), null, null);
        	}
        }
        

        就是先执行后面的前置通知,然后执行后置通知的内容,继续执行 proceed 方法。

      5. 再执行MethodBeforeAdviceInterceptor拦截器的invoke方法

        @Override
        public Object invoke(MethodInvocation mi) throws Throwable {
        	this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        	return mi.proceed();
        }
        
      6. 这个时候再次来到 proceed 方法,此时的下标变为 4,还是执行 MethodBeforeAdviceInterceptor

      7. 开始回溯了,因为方法都已经入栈了,依次执行了前置通知、后置通知、返回通知。

      Spring AOP源码解析

4、总结

1、@EnableAspectJAutoProxy 开启AOP功能

2、@EnableAspectJAutoProxy会注册一个AnnotationAwareAspectJAutoProxyCreator组件

3、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器

4、容器创建过程

​ 1、registerBeanPostProcessor()注册所有后置处理器,会创建AnnotationAwareAspectJAutoProxyCreator对象

​ 2、finishBeanFactoryInitialize()初始化剩下的单实例bean

​ 1)、创建业务逻辑组件和切面组件

​ 2)、AnnotationAwareAspectJAutoProxyCreator会拦截组件的创建过程

​ 3)、组件创建完成之后,判断组件是否需要增强

​ 是:切面的通知方法包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib代理)

5 、执行目标方法:

​ 1、代理对象执行目标方法

​ 2、CglibProxy.intercept()

​ 1、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)

​ 2、利用拦截器的链式机制,依次进入每一个拦截器进行执行

​ 3、效果

​ 正常执行:前置通知->目标方法->后置通知->返回通知

​ 异常执行: 前置通知->目标方法->后置通知->异常通知

你若盛开 清风自来 peace!

相关标签: spring java