NOTE

2.2 When Does AnnotationAwareAspectJAutoProxyCreator Take Effect?

Trace postProcessBeforeInstantiation and postProcessAfterInitialization while creating singleton Beans

JavaCreated Updated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. Continue Studying BeanPostProcessor.postProcessBeforeInstantiation and postProcessAfterInitialization

Let the breakpoint continue until:

  • AbstractAutoProxyCreator#postProcessBeforeInitialization
postProcessBeforeInitialization:282, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsBeforeInitialization:407, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1622, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:553, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:481, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:756, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:542, AbstractApplicationContext (org.springframework.context.support)
<init>:84, AnnotationConfigApplicationContext (org.springframework.context.annotation)
main:26, AopConfig
  • AbstractAutoProxyCreator#postProcessAfterInitialization
postProcessAfterInitialization:293, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsAfterInitialization:421, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1634, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:553, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:481, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:756, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:542, AbstractApplicationContext (org.springframework.context.support)
<init>:84, AnnotationConfigApplicationContext (org.springframework.context.annotation)
main:26, AopConfig

2. Create Other Singleton Beans

Our own AopConfig, Calc, and LogAspect Beans are all created inside org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization.

Before and after creation, they respectively pass through these two AnnotationAwareAspectJAutoProxyCreator post-process methods:

  • AbstractAutoProxyCreator#postProcessBeforeInitialization
  • AbstractAutoProxyCreator#postProcessAfterInitialization

For the Bean-creation process, see 4. Instantiate All Non-Lazy Singleton Beans.

2.1. Give BeanPostProcessors a Chance to Return a Proxy Object

  • AbstractAutowireCapableBeanFactory#createBean

From this logic, before the Bean instance is actually created, BeanPostProcessors are first given a chance to return a proxy object. If one is returned, it is used; otherwise the Bean is actually created.

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        // Give BeanPostProcessors a chance to return a proxy object.
        // Calc executes this logic.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }

    // The logic that actually creates the Bean.
    // Same as "2.1 How the AnnotationAwareAspectJAutoProxyCreator Bean instance is created":
    // create the AnnotationAwareAspectJAutoProxyCreator Bean instance.
    // That is:
    // - doCreateBean
    //   - createBeanInstance (create Bean instance)
    //   - populateBean (assign values to Bean instance)
    //   - initializeBean
    //     - invokeAwareMethods (if it implements an Aware interface, perform the corresponding processing)
    //     - applyBeanPostProcessorsBeforeInitialization (call BeanPostProcessor.beforeInitialization)
    //     - invokeInitMethods (execute custom initialization methods such as @PostInit)
    //     - applyBeanPostProcessorsAfterInitialization (call BeanPostProcessor.afterInitialization)
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isDebugEnabled()) {
        logger.debug("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
}
  • AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    // Obtain all BeanPostProcessors and execute postProcessBeforeInstantiation.
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        // Obtain all BeanPostProcessors and execute postProcessAfterInitialization.
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

2.1.1. Execute postProcessBeforeInstantiation

  • AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // Iterate over all BeanPostProcessors.
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            // If it is an InstantiationAwareBeanPostProcessor
            // (our AspectJAnnotationAutoProxyCreator).
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // Execute postProcessBeforeInstantiation.
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            // Return only if it is not null.
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

2.1.2. Execute postProcessAfterInitialization

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

    Object result = existingBean;
    // Iterate over all BeanPostProcessors.
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // Execute postProcessAfterInitialization.
        result = processor.postProcessAfterInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub