AbstractAdvisorAutoProxyCreator for Springboot Source Analysis

Summary:

Spring's proxies are mainly divided into ProxyCreatorSupport s and ProxyProcessorSupport in the upper level, the former based on the proxy factory, the latter based on the postprocessor, or think of the postprocessor as the automatic proxy.When there are more beans in the spring container that require aop weaving, simply using ProxyFacotryBean will undoubtedly add a lot of work (because each Bean! Has to be written manually).So the automatic proxy works.

Automatically create proxy classifications in Spring

Internally, Spring uses BeanPostProcessor to automate proxy generation.The implementation class of the automatic proxy creator based on BeanPostProcessor generates proxy instances for matching beans when instantiated in containers according to some rules.Proxy creators can be divided into three categories:

  • Automatic Proxy Generator based on Bean Configuration Name Rule: Proxy Creator that allows automatic creation of proxy instances for a set of beans with a specific configuration name, implemented as BeanNameAutoProxyCreator
  • An automatic proxy creator based on the Advisor matching mechanism scans all Advisors in the container, automatically applies these facets to the matching beans, and the implementation class is DefaultAdvisor AutoProxyCreator (it also supports prefix matching)
  • Automatic Proxy Generator based on AspectJ annotations in Bean: Create proxy instances automatically for beans that contain an entry with AspectJ annotations. The implementation class is AnnotationAwareAspectJAutoProxyCreator, which is imported by our @EnableAspectJAutoProxy, which is also the most widely used way we are today~

BeanNameAutoProxyCreator

    package com.github.dqqzj.springboot.aop;
    
    import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    
    /**
     * @author qinzhongjian
     * @date created in 2019-08-25 09:43
     * @description: TODO
     * @since JDK 1.8.0_212-b10
     */
    @Component
    public class MyBeanNameAutoProxyCreator extends BeanNameAutoProxyCreator {
        @PostConstruct
        public void init() {
            super.setBeanNames("aopService", "abstractAutoProxyCreatorService");
            super.setInterceptorNames("myMethodBeforeAdvice");
        }
    
    }

If you want to replace the @EnableAspectJAutoProxy auto-creator AnnotationAwareAspectJAutoProxyCreator that you registered by default with your own registered @Bean, you can register a Bean with the following name:

    // Manually register an automatic proxy creator by the name of AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME
    @Bean(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME) 
    public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
        ...
    }

AbstractAutoProxyCreator

    public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
            implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
            ...
    }

AbstractAutoProxyCreator is an abstract implementation of the automatic proxy creator.Most importantly, it implements the SmartInstantiationAwareBeanPostProcessor interface and therefore gets involved in the process of instantiating Spring IoC container beans, as shown in AbstractAutowireCapableBeanFactory

    try {
                // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
                if (bean != null) {
                    return bean;
                }
            }

This generally does not work, however, because this resolveBeforeInstantiation is only for a custom targetsource, since a custom Targetsource is not a spring bean and certainly does not require a subsequent series of instantiation initializations.So proxy can be done directly in resolveBeforeInstantiation.Simply put, this code is negligible and generally not needed by developers.

How do I get resolveBeforeInstantiation to return bean s directly?

    package com.github.dqqzj.springboot.aop;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
    
    /**
     * @author qinzhongjian
     * @date created in 2019-08-25 11:35
     * @description: TODO
     * @since JDK 1.8.0_212-b10
     */
    public class AopServiceInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if (beanClass.isInstance(AopService.class)) {
                return new AopService();
            }
            return null;
        }
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }

This is spring's first use of a postprocessor. If this is returned directly, it's equivalent to breaking away from the IOC's life cycle. Dependent injection, property filling, and so on, are not handled, so it's important to be careful not to use this feature when using it.

There are two particularly important post-processing processes that follow during the initialization of bean s, with more or less impact on circular dependencies and even asynchronous annotation of things, and will continue to be analyzed later.

Summary:

SpringAOP should try to avoid creating its own AutoProxyCreator. Internal mechanisms and their complexity inevitably lead to other uncommon problems due to unexpected problems. There is little to share because I think it's critical to be familiar with this architect. The implementation of each subclass is quite different, but you want all of themIt is unrealistic for the Department to keep in mind or be familiar with his design. Only by being familiar with his design can problems be easily solved by turning over the source code.

Keywords: Java Spring github SpringBoot JDK

Added by env3rt on Sun, 25 Aug 2019 08:43:57 +0300