springboot startup process (XI) processing section AOP

All articles

https://www.cnblogs.com/lay2017/p/11478237.html

 

text

two core spring is ioc and aop. In about ioc dependency injection article, we learned how to create Bean according to BeanDefinition, and then deal with @Autowired @Resource two notes in BeanPostProcessor, the automatic injection Bean.

This article will explain another piece of the core content, aop section.

 

AOP auto-configuration

First, aop section based on the auto-configuration springboot. If you do not understand the automatic configuration, refer to the autoconfiguration mechanism article.

To this end, we first find the class AopAutoConfiguration aop autoconfiguration

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = false)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
            matchIfMissing = false)
    public static class JdkDynamicAutoProxyConfiguration {

    }

    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
            matchIfMissing = true)
    public static class CglibAutoProxyConfiguration {

    }

}

We will understand Cglib as the main object, you can see a @EnableAspectJAutoProxy comment on CglibAutoProxyConfiguration, it means open proxy section, we open the annotation

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

    //
}

We see, @ Import annotation imported AspectJAutoProxyRegistrar. In the article automatically configured , we learned ConfigurationClassParser will deal @Import comment. Here we are no longer concerned about how to deal with @Import annotations directly open class look AspectJAutoProxyRegistrar

class AspectJAutoProxyRegistrar the implements ImportBeanDefinitionRegistrar { 

    @Override 
    public  void registerBeanDefinitions (AnnotationMetadata importingClassMetadata, the BeanDefinitionRegistry Registry) {
         // Register the agent automatically cut creator 
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary (Registry); 

        // omitted 
    } 

}

 

Follow registerAspectJAnnotationAutoProxyCreatorIfNecessary

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

Continue to follow up registerAspectJAnnotationAutoProxyCreatorIfNecessary

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
        BeanDefinitionRegistry registry, @Nullable Object source) {

    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

We see that call registerOrEscalateApcAsRequired method specifies a class AnnotationAwareAspectJAutoProxyCreator, this class will create a proxy class

 

Follow registerOrEscalateApcAsRequired method

private static BeanDefinition registerOrEscalateApcAsRequired(
        Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

    //
    // 构建BeanDefinition
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    // 注册到Bean容器
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

We can see, eventually registered to Bean containers as BeanDefinition exist. We can think aop automatic configuration process is to create BeanDefinition AnnotationAwareAspectJAutoProxyCreator this class.

 

Registration AnnotationAwareAspectJAutoProxyCreator

First, let's take a look at the inheritance structure AnnotationAwareAspectJAutoProxyCreator

We can see, AnnotationAwareAspectJAutoProxyCreator ultimately realized BeanPostProcessor, BeanPostProcessor that is when it is created as Bean?

Here, we have to return refresh method refresh container process, follow the refresh method AbstractApplicationContext

public  void Refresh () throws BeansException, {IllegalStateException
     the synchronized ( the this .startupShutdownMonitor) {
         //  

        the try {
             //  

            // Register BeanDefinition container 
            invokeBeanFactoryPostProcessors (beanFactory); 

            // Sign post processor container 
            registerBeanPostProcessors (beanFactory); 

            //
         }
         //
     } 
}

After registration BeanDefinition, it will be converted to the BeanPostProcessor of BeanDefinition Bean registered with the container. After the end of registerBeanPostProcessors, AnnotationAwareAspectJAutoProxyCreator exists in the form of Bean in the BeanFactory.

 

Trigger AnnotationAwareAspectJAutoProxyCreator

Next, we look at AnnotationAwareAspectJAutoProxyCreator after being registered as Bean, is in what position is triggered. Front, IOC dependency injection article we mentioned createBean method, Bean will be created according to BeanDefinition.

Follow createBean method of AbstractAutowireCapableBeanFactory

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    //

    try {
        // BeanPostProcessors 调用
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    //

    try {
        // 创建实例对象
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        //
        return beanInstance;
    }
    //
}

We see before doCreateBean, triggering resolveBeforInstantiation first method, called AnnotationAwareAspectJAutoProxyCreator.

 

Analytical section

Follow resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //
            if (targetType != null) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                //
            }
        }
        //
    }
    return bean;
}

Continue to follow up applyBeanPostProcessorBeforeInstantiation method

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // 触发postProcesBeforeInstantiation
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

Continue postProcessBeforeInstantiation method of follow up AbstractAutoProxyCreator

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        //
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    //
    return null;
}

isInfrastructureCLass returns false, follow AspectJAwareAdvisorAutoProxyCreator of shouldSkip

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    // 返回所有的通知,如@Before @After @AfterThrowing @Round
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    for (Advisor advisor : candidateAdvisors) {
        if (advisor instanceof AspectJPointcutAdvisor &&
                ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
            return true;
        }
    }
    return super.shouldSkip(beanClass, beanName);
}

Here findCandidateAdvisors method will be obtained from beanFactory class metadata annotations @Aspect then acquired defined therein Advisor.

At this point, we have received complete analytical work cut parts.

 

Agent enhancements

Back AbstractAutowireCapableBeanFactory method of createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    //

    try {
        // BeanPostProcessors 调用
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    //

    try {
        // 创建实例对象
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        //
        return beanInstance;
    }
    //
}

Acquired Advisor, then take a look Advisor is enhanced to process the Bean, follow doCreateBean

protected Object doCreateBean ( Final String the beanName, Final RootBeanDefinition MBD, Final @Nullable Object [] args)
         throws BeanCreationException {
     //
 
    IF (instanceWrapper == null ) {
         // create an instance 
        instanceWrapper = createBeanInstance (the beanName, MBD, args); 
    } 
    //
 
    Object exposedObject = the bean;
     the try {
         // automatic injector 
        populateBean (the beanName, MBD, instanceWrapper);
         // initialize Bean, create inlet agent
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }

    //
    return exposedObject;
}

We find initializeBean, this initialization Bean's entrance, began to focus on enhancing agent part from here, follow initializeBean method

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    //
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

Continue to follow up applyBeanPostProcessorsAfterInitialization method

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

postProcessAfterInitialization method will be called AbstractAutoProxyCreator here, and follow-up method

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

Continue to follow up wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    //

    // 获取适用于当前Bean的Advisors
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 创建代理
        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;
}

getAdvicesAndAdvisorsForBean method will get to enhance the Advisor to the Bean, and then createProxy will create a proxy class, and all the way to return, if it is a singleton, then registered into the cache

Creating an agent to follow up to see createProxy

protected Object createProxy (<?> Class beanClass, the beanName @Nullable String, 
        @Nullable Object [] specificInterceptors, the TargetSource TargetSource) { 

    // 

    // Get Available Advisor 
    Advisor [] = Advisors buildAdvisors (the beanName, specificInterceptors); 
    proxyFactory.addAdvisors ( Advisors); 

    // 
    // create and return a proxy object 
    return proxyFactory.getProxy (getProxyClassLoader ()); 
}

Follow getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

createAopProxy will return Cglib implemented or the implementation jdk dynamic proxy according to the conditions, then call them getProxy way to get a proxy object

 

to sum up

Many details of the omitted herein, is generally from logic: aop autoconfiguration -> Analytical @Aspect aspect instance -> reinforcing agents, such drafting of a logic.

The core is automatically configured to import a AnnotationAwareAspectJAutoProxyCreator, which implements the BeanPostProcessor. So before you create the Bean instance of an object triggers resolve @Aspect cut objects to acquire Advisor. After generating the Bean instance of an object, it will then trigger the analytical results of the class before the agent to enhance Bean instance of an object, enhanced Advisor from. Acting enhanced realize there cglib and jdk dynamic proxy two kinds.

Finally, through enhanced if the agent Bean is singleton, as before, will be added to the cache object.

 

Guess you like

Origin www.cnblogs.com/lay2017/p/11519411.html