曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】) (2)

在前面的spring流程中,第三步,就会去查找实现了BeanPostProcessor的bean definition集合,其中,就会包含AspectJAwareAdvisorAutoProxyCreator 这个bean definition;然后通过getBean方法,将这个bean definition实例化为bean。(这个过程,类似于通过class来创建对象)

这个步骤的具体实现入口在:

public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); /** * 配置beanFactory */ prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // 入口在这里!这里面会去 getBean registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); /** * 这里对单例bean、且lazy-init=false进行实例化 */ finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } } }

具体跟进去后,在如下位置,809行,就通过getBean,获取到了AspectJAwareAdvisorAutoProxyCreator这个bean了:

曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)

2.AspectJAwareAdvisorAutoProxyCreator对target bean进行后置处理,生成代理

在“spring大致启动流程”中的第四步,去预先实例化bean时,会进入以下逻辑:

public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { ... try { ... // Check for listener beans and register them. registerListeners(); /** * 入口在这里。这里对单例bean、且lazy-init=false进行实例化 */ finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } } }

然后会进入以下逻辑:

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons public void preInstantiateSingletons() throws BeansException { if (this.logger.isInfoEnabled()) { this.logger.info("Pre-instantiating singletons in " + this); } // 其中 this.beanDefinitionNames 保存了所有的bean definition名称 for (String beanName : this.beanDefinitionNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 实例化那些:非抽象、单例、非lazy-init的bean definition if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { ... if (isEagerInit) { getBean(beanName); } } else { getBean(beanName); } } } }

所以,这里就是对那些:非抽象、单例、非lazy-init的bean definition 进行实例化。

我们这里,大家看下当前容器中包含的全部的bean definition:

曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)

我这边的demo,第一个要实例化的bean,就是performer。在getBean()处理performer这个bean的过程中,会经历以下的流程:

曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)

其中,AspectJAwareAdvisorAutoProxyCreator 作为beanPostProcessor,在实例化performer这个bean时,有两个时间点参与进来。

哪两个时间点呢,大家再看看,AspectJAwareAdvisorAutoProxyCreator 的类图:

曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)

其实它不止实现了BeanPostProcessor接口,它还实现了InstantiationAwareBeanPostProcessor接口。这个多出来的接口,干嘛的?大家看看它的方法就知道了:

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { // 注意,before Instantiation的意思是,实例化之前调用 Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException; // 这个,实例化之后调用 boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException; ...无关方法 }

所以,InstantiationAwareBeanPostProcessor扩展了两个时间点出来,一个是实例化前,一个是实例化后。

什么叫实例化?把一个对象new出来,通俗来讲,就叫做实例化。

在spring的getBean流程里,实例化肯定是早于初始化的。所以,一个bean,会经历如下顺序(大家直接看前面点的图,更清晰):

InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypydw.html