[Spring] AOP annotations manner mechanism

I. Overview

In Spring AOP:

  • AnnotationAwareAspectJAutoProxyCreator is based Bean in AspectJ annotation to achieve automatic proxy, complete the entry point in the process of enhancing Bean created.
  • Other implementations of Spring AOP can see [Spring] AOP Base

For the Spring AOP mode using annotations, we open the configuration AOP comment

  • You can use XML ways:
<!-- 自动生成代理  底层就是AnnotationAwareAspectJAutoProxyCreator -->
<aop:aspectj-autoproxy />
  • Or use as annotations marked on the configuration class @EnableAspectJAutoProxy 注解
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
    //业务逻辑类加入容器中
    @Bean 
    public UserDao userDao(){
        return new UserDao();
    }
    //切面类加入到容器中
    @Bean
    public MyAspect myAspect(){
        return new MyAspect();
    }
}
  • Either XML or @EnableAspectJAutoProxyunderlying implementation is AnnotationAwareAspectJAutoProxyCreator

Two, @ EnableAspectJAutoProxy annotation analysis

This annotated source code:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    ...
}

  Click this annotation found a @Import notes, this is one of the class notes directly into the Spring container, look AspectJAutoProxyRegistrar this class, which is a registrar, we can manually register such a bean into the container, Spring Source will AnnotationAwareAspectJAutoProxyCreator by Regist registered to Spring container on which @Import some conclusions accessible [Spring] IOC Base in initialization mode Bean part

  In AspectJAutoProxyRegistrarclass, you can analyze internalAutoProxyCreatorthatAnnotationAwareAspectJAutoProxyCreator

Third, the analysis AnnotationAwareAspectJAutoProxyCreator

Then analyze this critical category:
First look at the inheritance system AnnotationAwareAspectJAutoProxyCreator

  • AnnotationAwareAspectJAutoProxyCreator
    • -->AspectJAwareAdvisorAutoProxyCreator
      • -->AbstractAdvisorAutoProxyCreator
        • -->AbstractAutoProxyCreator
          • implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

Such an analysis can be achieved BeanPostProcessor BeanFactoryAware and interfaces, so that these have a postprocessor characteristics and Aware Interface Characteristics

We can be analyzed in two ways mechanism of this class:

  1. Watch post-processor (things to do before and after bean initialization is complete),
  2. Automatic assembly BeanFactory

Fourth, the implementation process

Analyze the following process execution:

1. registerBeanPostProcessors()

  Sign AnnotationAwareAspectJAutoProxyCreator in a container

The first step: the incoming class configuration, create ioc container
Step two: Register configuration class, call the refresh () refresh container
The third step: registerBeanPostProcessors(beanFactory) the registered bean post-processors to facilitate interception create the bean, as follows:
(first step): first get ioc container is already defined all BeanPostProcessor need to create objects

(Second step): to add another container in the BeanPostProcessor
(third step): Sunrise implements BeanPostProcessor PriorityOrdered interface;
(fourth step): Give the container to achieve a registered BeanPostProcessor Ordered interface;
(fifth step ): registration not realize priority BeanPostProcessor interface;

Source of this method are as follows:

public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//获取ioc容器已经定义了的需要创建对象的所有后置处理器
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // Register BeanPostProcessorChecker that logs an info message when
        // a bean is created during BeanPostProcessor instantiation, i.e. when
        // a bean is not eligible for getting processed by all BeanPostProcessors.
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // Separate between BeanPostProcessors that implement PriorityOrdered, 
        // Ordered, and the rest.
//对后置处理进行分类
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }
//首先注册实现了PriorityOrdered 接口的后置处理器
        // First, register the BeanPostProcessors that implement PriorityOrdered.
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
//然后注册实现了Ordered接口的后置处理器
        // Next, register the BeanPostProcessors that implement Ordered.
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);
//注册常规的(即没有实现优先级接口)的后置处理器
        // Now, register all regular BeanPostProcessors.
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // Finally, re-register all internal BeanPostProcessors.
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

internalAutoProxyCreator[ AnnotationAwareAspectJAutoProxyCreator] Is to achieve a post processor Ordered interface registration process, in fact, is to create BeanPostProcessor objects stored in the container, call flow method
getBean () -> doGetBean () -> getSingleton () - > finally come createBean () method,

Call getBean ()
Call getBean ()

Call doGetBean in the getBean
Call doGetBean in the getBean

In doGetBean the call getSingleton
In doGetBean the call getSingleton

getSingleton method call returns a null
getSingleton method call returns a nul

In doGetBean start calling createBean method
In doGetBean start calling createBean method

Calls in createBean method doCreateBean method, the flow of execution of this method are:

  • Create an instance of the Bean:
  • populateBean; assigned to the various properties of the bean
  • initializeBean: initializing the bean; In this process:
    • invokeAwareMethods (): method for processing a callback interface Aware
    • applyBeanPostProcessors the Before the Initialization (): Application post-processor postProcess the Before the Initialization ()
    • invokeInitMethods (); custom initialization method performed
    • applyBeanPostProcessors the After the Initialization (); postProcess postprocessor performs the After the Initialization ();
    • BeanPostProcessor (AnnotationAwareAspectJAutoProxyCreator) successfully created; aspectJAdvisorsBuilder

(Sixth step): The BeanPostProcessor registered to the BeanFactory; beanFactory.addBeanPostProcessor (postProcessor);

These are created and the process of registration AnnotationAwareAspectJAutoProxyCreator

2. finishBeanFactoryInitialization()

The fourth step: the implementation of finishBeanFactoryInitialization () : complete BeanFactory initialization, create a single instance of the rest of the bean.

(First step): traversing get all the container Bean, in order to create objects getBean (beanName);
getBean-> doGetBean () -> getSingleton () ->

(Second step): Create a bean

The following is doGetBean process portion Source :

protected <T> T doGetBean(
            final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {
        final String beanName = transformedBeanName(name);
        Object bean;
//这里先尝试获取单实例bean
        // Eagerly check singleton cache for manually registered singletons.
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
        ....
        }else {
                // Create bean instance.
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            try {
    //这里创建Bean实例
                                return createBean(beanName, mbd, args);
                            }
                ...
                }       
      ...
            return (T) bean;
    }
  • Get the current existing cache bean, if they can get to, indicating bean before had been created, directly, or re-create; just create a good Bean will be cached
  • createBean (), create the bean, the following method of analysis is the process createBean:

  • 1 resolveBeforeInstantiation(beanName, mbdToUse): The desired post-processor can return a proxy object; if the agent can return the object to use, if not to continue

    • Post-processor attempts to return to the object;
    • bean = applyBeanPostProcessorsBeforeInstantiation():拿到所有后置处理器,如果是 InstantiationAwareBeanPostProcessor; 就执行postProcessBeforeInstantiation
    if (bean != null) {
    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    }
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
    //如果是这个类型的处理器,就执行其postProcessBeforeInstantiation() 方法
    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    if (result != null) {
    return result;
    }
    }
    }
    return null;
    }
    • AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean的实例
    • BeanPostProcessor是在Bean对象创建完成初始化前后调用的
    • InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的
  • 2.doCreateBean(beanName, mbdToUse, args):真正的去创建一个bean实例,此方法的流程在上面已经介绍 (第三.(五)步中图片下面)

3. InstantiationAwareBeanPostProcessor后置处理器的执行逻辑

  经过上面的分析可以知道,在所有bean创建之前会有一个拦截:由于 AnnotationAwareAspectJAutoProxyCreator 是一个InstantiationAwareBeanPostProcessor 类型的后置处理器,它会调用postProcessBeforeInstantiation()方法

(A): Before each bean to create, call postProcessBeforeInstantiation ();
focus on business logic classes and cut class created

  Source as follows:

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);
        
//1.判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
        if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }

//2.判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)
//3.是否需要跳过
//获取候选的增强器(切面里面的通知方法)
//【List<Advisor> candidateAdvisors】每一个封装的通知方法的
//增强器是 InstantiationModelAwarePointcutAdvisor类型;
//判断每一个增强器是否是 AspectJPointcutAdvisor 类型的,
//如果是,返回true;如果不是调用父类的【shouldSkip()-->永远返回false】
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        if (beanName != null) {
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
            if (targetSource != null) {
                this.targetSourcedBeans.add(beanName);
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
        }

        return null;
    }

(B): Once you have created the business class object after calling execute postProcessAfterInitialization ;

  Source as follows:

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // Create proxy if we have advice.
/*1.获取当前bean的所有增强器(通知方法) getAdvicesAndAdvisorsForBean() 内部流程:
*  1.1找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
*  1.2获取到能在bean使用的增强器。
*  1.3给增强器排序
*/
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
//2.保存当前bean在advisedBeans中;
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            
/*3. 如果当前bean需要增强,创建当前bean的代理对象;
 *  1)、获取所有增强器(通知方法)
 *  2)、保存到proxyFactory
 *  3)、创建代理对象:Spring自动决定
 *      JdkDynamicAopProxy(config);jdk动态代理;
 *      ObjenesisCglibAopProxy(config);cglib的动态代理;
 *  4)、给容器中返回当前组件增强了的代理对象;
 *  5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
*/
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

4. Target execution method

  After the above process, the container is to get this component of the proxy object , when the method of execution of the target, the proxy object executes the process of notification methods.

Proxy object
Proxy object

  After entering through several Debug out, can enter into CglibAopProxy.intercept () method, which executes a method of intercepting targets

Source as follows:

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
    Class<?> targetClass = null;
    Object target = null;
    try {
        if (this.advised.exposeProxy) {
            // Make invocation available if necessary.
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }
        // May be null. Get as late as possible to minimize the time we
        // "own" the target, in case it comes from a pool...
        target = getTarget();
        if (target != null) {
            targetClass = target.getClass();
        }
    
/*
* 1. 根据ProxyFactory对象获取将要执行的目标方法拦截器链;
*   方法源码见下面
*   1.1 List<Object> interceptorList保存所有拦截器 5
*   一个默认的ExposeInvocationInterceptor 和 4个增强器;
*   1.2 遍历所有的增强器,将其转为Interceptor;
*   registry.getInterceptors(advisor);
*     1.2.1 将增强器转为List<MethodInterceptor>;
*     1.2.2 如果是MethodInterceptor,直接加入到集合中
*     1.2.3 如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
*   转换完成返回MethodInterceptor数组;
*/  
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        Object retVal;
        // Check whether we only have one InvokerInterceptor: that is,
        // no real advice, but just reflective invocation of the target.
        if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
/*
* 2.如果没有拦截器链,直接执行目标方法;
*  拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
*/
            // We can skip creating a MethodInvocation: just invoke the target directly.
            // Note that the final invoker must be an InvokerInterceptor, so we know
            // it does nothing but a reflective operation on the target, and no hot
            // swapping or fancy proxying.
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            retVal = methodProxy.invoke(target, argsToUse);
        }
        else {
    
/*
* 3. 如果有拦截器链,把需要执行的目标对象,目标方法,
*   拦截器链等信息传入,创建一个 CglibMethodInvocation 对象,
*   并调用Object retVal =  mi.proceed();
*/
            // We need to create a method invocation...
            retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
        }
        retVal = processReturnType(proxy, target, method, retVal);
        return retVal;
    }
    finally {
        if (target != null) {
            releaseTarget(target);
        }
        if (setProxyContext) {
            // Restore old proxy.
            AopContext.setCurrentProxy(oldProxy);
        }
    }
}

A first portion to give interceptor chain

Source above method call 1

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
    MethodCacheKey cacheKey = new MethodCacheKey(method);
    List<Object> cached = this.methodCache.get(cacheKey);
    if (cached == null) {
        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                this, method, targetClass);
        this.methodCache.put(cacheKey, cached);
    }
    return cached;
}

The above method is called in the following method:

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, Class<?> targetClass) {

        // This is somewhat tricky... We have to process introductions first,
        // but we need to preserve order in the ultimate list.

/**
* 1.1 List<Object> interceptorList保存所有拦截器 5
*   一个默认的ExposeInvocationInterceptor 和 4个增强器;
*/
        List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
        Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();


    for (Advisor advisor : config.getAdvisors()) {
            if (advisor instanceof PointcutAdvisor) {
                // Add it conditionally.
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                
                
/*
1.2 遍历所有的增强器,将其转为Interceptor;
*/
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        if (mm.isRuntime()) {
                            // Creating a new object instance in the getInterceptors() method
                            // isn't a problem as we normally cache created chains.
                            for (MethodInterceptor interceptor : interceptors) {
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }
                        }
                        else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            }
            else if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                    Interceptor[] interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            }
            else {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }

        return interceptorList;
    }

The above method and calling the following methods:

@Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
        Advice advice = advisor.getAdvice();
/*
* 1.2.1 将增强器转为List<MethodInterceptor>;
* 1.2.2 如果是MethodInterceptor,直接加入到集合中,如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
* 1.2.3转换完成返回MethodInterceptor数组;
*/
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
        for (AdvisorAdapter adapter : this.adapters) {
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }
        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        }
        return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
    }

  After the above 1 we get the interceptor chain (each notification method has been packed into interceptor method using MethodInterceptor mechanism)

A second portion, the interceptor chain triggering process

Source in the above method called 3

public Object proceed() throws Throwable {
        //  We start with an index of -1 and increment early.
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            // Evaluate dynamic method matcher here: static part will already have
            // been evaluated and found to match.
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            }
            else {
                // Dynamic matching failed.
                // Skip this interceptor and invoke the next in the chain.
                return proceed();
            }
        }
        else {
            // It's an interceptor, so we just invoke it: The pointcut will have
            // been evaluated statically before this object was constructed.
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
  • If not executed as interceptors and interceptors index array size -1 execution target method, or the interceptor (assigned to the last interceptor) performs the target method;
  • Each chain Get interceptor interceptor invoke method performs, each interceptor interceptor wait for the next execution returns again after completion of execution;
    • Interceptor chain mechanism, to ensure the order of execution of the target method and the notification method;

Chained calls
Chained calls

to sum up

  1. @EnableAspectJAutoProxy open AOP functionality
  2. @EnableAspectJAutoProxy container will register a component AnnotationAwareAspectJAutoProxyCreator
  3. AnnotationAwareAspectJAutoProxyCreator is a post-processor;
  4. Container creation process:
    • registerBeanPostProcessors (): registered post processor; create objects AnnotationAwareAspectJAutoProxyCreator
    • finishBeanFactoryInitialization (): initializing the remaining single instance of the bean
      • Create business logic components and section components;
      • AnnotationAwareAspectJAutoProxyCreator interception creation process components;
      • After complete assembly created, determines whether the component needs to be enhanced, if desired to enhance: the notification section to a method of packaging a booster (Advisor); create a proxy object (CGLIB) to business logic component;
  5. Execution of the target method: proxy object to perform target method
    • CglibAopProxy.intercept();
      • The method to obtain the target interceptor chain (booster packaged interceptor MethodInterceptor)
      • Use interceptor chain mechanism, in order to enter each interceptor execution;
      • effect:
        • Normal execution: Front notice - "target method -" after advice - "Back to News
        • - "target method -" after advice - "abnormal notice before advice: abnormal

Guess you like

Origin www.cnblogs.com/haoworld/p/springaop-zhu-jie-fang-shi-shi-xian-ji-zhi.html