[learning notes of Spring column] - integrate AOP dynamic proxy into Bean's life cycle

This article is learning Chapter 10 of Spring hand column Notes, mainly record some of my debug debugging process, which is convenient for later review. For specific study, you can go to this column and highly recommend it.

programme

In fact, after the implementation of the core functions of AOP, it is not difficult to integrate these functions and services into Spring, but to solve several problems, including: how to integrate dynamic agents into the Bean life cycle through BeanPostProcessor, and how to assemble various pointcut, interception and front-end functions and adapt the corresponding agents. The overall design structure is shown in the figure below:

  • In order to instantiate the proxy objects configured in xml, that is, some class objects in the aspect, during the object creation process, the methods provided by BeanPostProcessor need to be used, because the methods in this class can act on the extension information of the modified Bean object before and after the initialization of the Bean object. However, it is necessary to implement new interfaces and implementation classes in BeanPostProcessor, so as to obtain the corresponding class information.
  • However, because the proxy object is created instead of the ordinary object in the previous process, we need to precede the creation of other objects. Therefore, in the actual development process, we need to judge the Bean object in AbstractAutowireCapableBeanFactory#createBean first. If proxy is needed, we will directly return the proxy object. In the source code of Spring, there will be method splitting of createBean and doCreateBean
  • It also includes the specific functions of the interceptor to be solved, and provides some implementations of BeforeAdvice and AfterAdvice, so that users can use the aspect function more simply. In addition, it also includes the integration of packaging aspect expressions and interception methods, as well as agent factories that provide different types of agent methods to package our aspect services.

debug debugging

We need to directly judge whether the proxy object is created in the process of creating an abstract #, so we need to directly judge whether the proxy object is created in the process of creating an abstract #.
AbstractAutowireCapableBeanFactory.java

 protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
        Object bean = null;
        try {
            // Judge whether to return proxy Bean object
            bean = resolveBeforeInstantiation(beanName, beanDefinition);
            if (null != bean) {
                return bean;
            }
            // Instantiate Bean
            bean = createBeanInstance(beanDefinition, beanName, args);
           ...
        }
      ...
    }

AbstractAutowireCapableBeanFactory.java

protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) {
        Object bean = applyBeanPostProcessorsBeforeInstantiation(beanDefinition.getBeanClass(), beanName);
        if (null != bean) {
            bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
        }
        return bean;
    }


AbstractAutowireCapableBeanFactory.java

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

DefaultAdvisorAutoProxyCreator.java

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

        if (isInfrastructureClass(beanClass)) return null;

        Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();

        for (AspectJExpressionPointcutAdvisor advisor : advisors) {
            ClassFilter classFilter = advisor.getPointcut().getClassFilter();
            if (!classFilter.matches(beanClass)) continue;

            AdvisedSupport advisedSupport = new AdvisedSupport();

            TargetSource targetSource = null;
            try {
                targetSource = new TargetSource(beanClass.getDeclaredConstructor().newInstance());
            } catch (Exception e) {
                e.printStackTrace();
            }
            advisedSupport.setTargetSource(targetSource);
            advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
            advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher());
            advisedSupport.setProxyTargetClass(false);
			//Proxy methods will be called here.
            return new ProxyFactory(advisedSupport).getProxy();

        }

        return null;
    }

Keywords: Java Spring

Added by WebbDawg on Mon, 07 Feb 2022 02:36:35 +0200