NOTE
2.2 When Does AnnotationAwareAspectJAutoProxyCreator Take Effect?
Trace postProcessBeforeInstantiation and postProcessAfterInitialization while creating singleton Beans
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#postProcessBeforeInitializationAbstractAutoProxyCreator#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