0
点赞
收藏
分享

微信扫一扫

Spring Bean的初始化过程 initializeBean

想溜了的蜗牛 2022-12-16 阅读 143

目录

1.定义对象

2.注册对象

3.DEBUG Aware处理

4.完整初始化流程概览

5. applyBeanPostProcessorsBeforeInitialization

5.1 this.beanPostProcessors 里面的处理顺序

5.1.1 ApplicationContextAwareProcessor

5.1.2 ApplicationListenerDetector

5.1.3 WebApplicationContextServletContextAwareProcessor

5.1.4 ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor

5.1.5 BeanPostProcessorChecker

5.1.6 ConfigurationPropertiesBindingPostProcessor

5.1.7 CommonAnnotationBeanPostProcessor

5.1.8  AutowiredAnnotationBeanPostProcessor

5.1.9  AnnotationAwareAspectJAutoProxyCreator

5.1.10  DataSourceInitializerPostProcessor

5.1.11 MethodValidationPostProcessor

5.1.12  PersistenceExceptionTranslationPostProcessor

5.1.13 KafkaListenerAnnotationBeanPostProcessor

 6. invokeInitMethods

7.  applyBeanPostProcessorsAfterInitialization

7.1  ApplicationListenerDetector

7.2 BeanPostProcessorChecker

7.3  AnnotationAwareAspectJAutoProxyCreator

7.4  DataSourceInitializerPostProcessor

7.5 org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor

7.6 KafkaListenerAnnotationBeanPostProcessor


1.定义对象

public class Apple implements InitializingBean, BeanPostProcessor, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {

    @PostConstruct
    public void postConstruct(){
        System.out.println(" construct之后 进行... ");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(" 【before】 initialization....... ");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(" 【after】 initialization........ ");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(" 属性配置完成之后 进行了什么操作... ");
    }


    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println(classLoader);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println(beanFactory);
    }

    @Override
    public void setBeanName(String name) {
        System.out.println(name);
    }
}

上面是对象。

2.注册对象

@Configuration
@Import(Apple.class)
public class Config {
}

或者用@Bean方式注册Apple对象,效果都是一样的。

3.DEBUG Aware处理

之后进入到

 由这个顺序也知道,

BeanNameAware -> BeanClassLoaderAware -> BeanFactoryAware

 aware也是spring用来进行各种初始化的接口。通过aware接口,我们可以在Spring容器未完全初始化的时候,进行各种配置,拿到Spring容器的工具进行使用。

4.完整初始化流程概览

执行顺序 

invokeAwareMethods -> applyBeanPostProcessorsBeforeInitialization ->
invokeInitMethods -> applyBeanPostProcessorsAfterInitialization

刚才已经看了 invokeAwareMethods;

接下来继续往下看

5. applyBeanPostProcessorsBeforeInitialization

 这好像没什么区别,都是调用 postProcessBeforeInitialization 方法。

点击 getBeanPostProcessors() 进入到父类方法里了

里面的具体内容: 




由这里也可以看出,根据环境不同,这里的类会不同,顺序也会不同。
暂时按图2顺序,进行bean的前置处理分析。

 

 

5.1 this.beanPostProcessors 里面的处理顺序

5.1.1 ApplicationContextAwareProcessor

 从上图也可以看到,如果当前类,没有实现这些接口,就会直接返回。

那如果是这个接口会做些什么呢?

由图可知,当我们实现了这些接口,会调用所属接口的对应方法。

同一个类实现多个接口,会多次调用。

@Component
public class AppleContextAware implements EnvironmentAware, ApplicationEventPublisherAware {
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("事件发布类已经调用成功="+applicationEventPublisher);
    }

    @Override
    public void setEnvironment(Environment environment) {
        System.out.println("获取到当前Spring的 environment=" + environment);
    }
}

 可以看到,是按照  invokeAwareInterfaces 里的执行顺序进行操作的。

第一个,可以让我们实现多个aware。

这与 3.DEBUG Aware处理 的aware相比,就是所有的类都会经过 3.DEBUG Aware处理

但是如果是 自己定义了 RootBeanDefinition  且  isSynthetic 为true 就不会走入这个方法。

 RootBeanDefinition在AbstractBeanDefinition的基础上定义了更多属性,初始化Bean需要的信息基本完善。具体内容可以自行搜寻,这里不是重点。

5.1.2 ApplicationListenerDetector

无操作。

5.1.3 WebApplicationContextServletContextAwareProcessor

当前处理器,没有实现自己的前置处理,而是复用了父类的前置处理。

从内容也可以看出来,是获取servlet上下文与配置。

5.1.4 ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor

ImportAwareBeanPostProcessor 是 ConfigurationClassPostProcessor 的静态内部类。

 

 所以为了进一步了解这里到底怎么操作的。需要进一步查看  getImportingClassFor

 方法里面太绕了,总之是进入到了doConfiguration的操作。

当前类只要有@Import注解,且实现了ImportAware,就会拿出来进行操作。

(这部分找了一个多小时,都没找着头绪,我放弃了。先看别的,打好基础先。)

5.1.5 BeanPostProcessorChecker

 这个没做操作

5.1.6 ConfigurationPropertiesBindingPostProcessor

对这个的应用:

@Data
@Configuration
@ConfigurationProperties(prefix = "apple")
public class AppleProperties {

    private String name;

    private int price;

}

 yml配置:

5.1.7 CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor  通过继承InitDestroyAnnotationBeanPostProcessor @javax.annotation.PostConstruct @javax.annotation.PreDestroy 注解的支持。以及依据bean name依赖注入的@javax.annotation.Resource 支持。也支持WebServiceRef 注解,具有创建JAX-WS服务端点的能力。最后,处理器还支持EJB3(@EJB)

上面的这个两个方法,具体调用了 CommonAnnotationBeanPostProcessor 的父类InitDestroyAnnotationBeanPostProcessor。

在InitDestroyAnnotationBeanPostProcessor中分三个阶段完成这两个注解功能,分别为:

  1. 实现了MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法缓存初始化后和销毁前执行的方法。
  2. 实现了BeanPostProcessor.postProcessBeforeInitialization()用来执行@PostConstruct标注的方法。
  3. 实现了DestructionAwareBeanPostProcessor.postProcessBeforeDestruction()用来执行@PreDestroy标注的方法。

【下列方法是在  AbstractAutowireCapableBeanFactory 内】

AbstractAutowireCapableBeanFactory 在初始化bean之前,会对bean进行一个扫描。Autowired 和 Postconstruct 等等之类的,然后才是初始化。

 CommonAnnotationBeanPostProcessor  的  postProcessMergedBeanDefinition 首先调用了父类方法,支持了Init和Destory方法。

findResourceMetadata 里,支持了对@Resource以及WebService、Ejb的支持。

这个注入是在populateBean时进行注入的。

在初始化时,只会调用@PostConstruct注解的方法。

5.1.8  AutowiredAnnotationBeanPostProcessor

 默认父类方法,无操作。

5.1.9  AnnotationAwareAspectJAutoProxyCreator

默认父类方法,无操作。

5.1.10  DataSourceInitializerPostProcessor

默认实现,无操作。 

5.1.11 MethodValidationPostProcessor

 默认实现,无操作。 

5.1.12  PersistenceExceptionTranslationPostProcessor

  默认实现,无操作。 

5.1.13 KafkaListenerAnnotationBeanPostProcessor

默认实现,无操作。

 6. invokeInitMethods

在这里主要是执行 InitializingBean 的实现类的 afterPropertiesSet 方法

 

 

7.  applyBeanPostProcessorsAfterInitialization

 

和前置处理一样,都是一样的处理器。

只显示做了事情的PostProcessor.

7.1  ApplicationListenerDetector

ApplicationListenerDetector 就是为了进行注册监听器。

7.2 BeanPostProcessorChecker

BeanPostProcessorChecker检查xxx不适合所有的BeanPostProcessor来处理。即,存在出现“自动注入”不合适或无效的信息。


BeanPostProcessor是Spring的Bean工厂中的钩子(Hook),允许Spring框架在新创建Bean实例时对其进行定制化修改。它本身也是一个Bean,在通常情况下,其实例化顺序要优先于普通的Bean。因为有时BeanPostProcessor也会依赖一些Bean,所以,会存在一些普通Bean的实例化早于BeanPostProcessor的情况,因此就会造成一些问题。

7.3  AnnotationAwareAspectJAutoProxyCreator

在父类  AbstractAutoProxyCreator 里定义的

 进行AOP注册操作,具体实现过于复杂,将会开另外一篇文章进行探讨。

7.4  DataSourceInitializerPostProcessor

看别的文章,说是从beanFactory 是懒加载  DataSourceInitializerInvoker,从而对 dataSource进行处理。

7.5 org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor

在父类 AbstractAdvisingBeanPostProcessor 的默认方法。

可以看出来又是AOP相关内容。这些具体操作就得AOP相关内容进行分解。

7.6 KafkaListenerAnnotationBeanPostProcessor

对Kafka的一些操作,检查方法之类的。

 

OK。内容结束。

举报

相关推荐

0 条评论