Spring Bean管理核心组件——后置处理器详解

简介: Spring Bean管理核心组件——后置处理器详解

1.后置处理器是什么?

后置处理器就像组件,Spring很多事情就是交给组件去管理,使用就添加,不使用就不添加,非常符合开闭原则

以GenericApplicationContext为例:

    public static void main(String[] args) {
        GenericApplicationContext context=new GenericApplicationContext();
        context.registerBean("myConfig1",MyConfig1.class);//配置类
        context.registerBean(ConfigurationClassPostProcessor.class);//让Configuration注解生效的后置处理器
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);//让autowried生效的后置处理器
        context.registerBean(CommonAnnotationBeanPostProcessor.class);//让psotConstruct生效的后置处理器
        context.refresh();
        context.close();
          //如果是AnnotationConfigApplicationContext容器,不用手动添加配置类和执行refresh方法
//        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
//        context.close();        
    }

2.后置处理器分类

一、BeanFactory后置处理器

  1. ConfigurationClassPostProcessor
    扫描到@ComponentScan @Bean @Impoer @ImportResource并让其生效

二、Bean后置处理器

AutowiredAnnotationBeanPostProcessor:处理被@Autowired注解修饰的bean并注入


RequiredAnnotationBeanPostProcessor:处理被@Required注解修饰的方法


CommonAnnotationBeanPostProcessor:处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用

三、spring内置后置处理器

以上两种都是扩展功能,spring内部有自带的两个接口,这两个接口属于内置功能。扩展功能可能会失效,内置功能一定会执行。

  1. Aware接口:实现类可以注入bean的名字、注入BeanFactory 容器、注入 ApplicationContext 容器、注入${}解析器
  2. InitializingBean接口:提供了一种内置的初始化手段

3.后置处理器的执行时机

BeanFactory后置处理器:BeanFactory初始化之后,所有beanDefinition(其他工具类和后置处理器们)已经加载到beanFactory,但是实例未创建的时候


Bean后置处理器:Bean整个生命周期各阶段(实例化-依赖注入-初始化-销毁),有不同的处理器生效


Spring内置后置处理器:在Bean后置处理器执行结束后执行

refresh()之前:只是实例化了一个工厂,注册了一些内置的Bean和我们传进去的配置类。

refresh()内的逻辑如下:

prepareRefresh:刷新前的准备工作,主要是保存了容器的启动时间,启动标志等


ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory():把beanFactory取出来而已。XML模式下会在这里读取BeanDefinition


prepareBeanFactory:添加BeanFactory后置处理器、设置了忽略自动装配、指定自动装配对象的接口,设置了bean表达式解析器(${}),把环境变量注册成Singleton的Bean定义到工厂,然后调用


AbstractAutowireCapableBeanFactory的createBean方法实例化这些bean


postProcessBeanFactory:空方法,可能以后Spring会进行扩展


invokeBeanFactoryPostProcessors(beanFactory):执行已有的BeanFactory后置处理器,先执行排序的,最后执行没有排序的,先执行非Registry的后置处理器,后执行Registry的添加额外的bean定义的方法,Registry后置处理器也先执行排序的


registerBeanPostProcessors(beanFactory):实例化和注册Bean后置处理器


initMessageSource():初始化国际化资源处理器,通过读取特定配置文件,能实现不同语言的切换


initApplicationEventMulticaster():创建事件多播器,发出一个事件,任何一个配置类都可以作为监听器


onRefresh():模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情


registerListeners():注册监听器,带有@EventListener注解的配置类可以监听到播放的事件


finishBeanFactoryInitialization(beanFactory):实例化所有剩余的(非懒加载)单例,实例化的过程各种BeanPostProcessor开始起作用


finishRefresh():清除上下文资源缓存、初始化上下文的生命周期处理器,并刷新、发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作

补充

配置类:

//MainConfig.class是配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

①带上@Configuration注解的类,称为Full配置类,该类会被cgilb代理

②带有@Component,@Service 等注解的类,称为Lite配置类


Spring Bean的生命周期

实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为连Autowired注解都是没有解析的;


填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;


如果Bean实现了BeanNameAware接口,则调用setBeanName方法;


如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;


如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;


调用BeanPostProcessor的postProcessBeforeInitialization方法;


如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;


如果Bean定义了init-method方法,则调用Bean的init-method方法;


调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁;


如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用。

什么时候进行依赖注入

  1. 设置了懒加载,在调用getBean()时触发依赖注入
  2. 没有设置懒加载,在容器解析BeanDefiniton时触发依赖注入
相关文章
|
1月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
7天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
7天前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
59 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
1月前
|
XML Java 数据格式
Spring5入门到实战------3、IOC容器-Bean管理XML方式(一)
这篇文章详细介绍了Spring框架中IOC容器的Bean管理,特别是基于XML配置方式的实现。文章涵盖了Bean的定义、属性注入、使用set方法和构造函数注入,以及如何注入不同类型的属性,包括null值、特殊字符和外部bean。此外,还探讨了内部bean的概念及其与外部bean的比较,并提供了相应的示例代码和测试结果。
Spring5入门到实战------3、IOC容器-Bean管理XML方式(一)
|
1月前
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
|
1月前
|
XML Java 数据格式
Spring5入门到实战------5、IOC容器-Bean管理(三)
这篇文章深入探讨了Spring5框架中IOC容器的高级Bean管理,包括FactoryBean的使用、Bean作用域的设置、Bean生命周期的详细解释以及Bean后置处理器的实现和应用。
Spring5入门到实战------5、IOC容器-Bean管理(三)
|
1月前
|
XML Java 数据格式
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
这篇文章是Spring5框架的实战教程,主题是IOC容器中Bean的集合属性注入,通过XML配置方式。文章详细讲解了如何在Spring中注入数组、List、Map和Set类型的集合属性,并提供了相应的XML配置示例和Java类定义。此外,还介绍了如何在集合中注入对象类型值,以及如何使用Spring的util命名空间来实现集合的复用。最后,通过测试代码和结果展示了注入效果。
Spring5入门到实战------4、IOC容器-Bean管理XML方式、集合的注入(二)
|
1月前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
|
1月前
|
XML Java 数据格式
Spring5入门到实战------8、IOC容器-Bean管理注解方式
这篇文章详细介绍了Spring5框架中使用注解进行Bean管理的方法,包括创建Bean的注解、自动装配和属性注入的注解,以及如何用配置类替代XML配置文件实现完全注解开发。
Spring5入门到实战------8、IOC容器-Bean管理注解方式
|
1月前
|
Java Spring
Spring的AOP组件详解
该文章主要介绍了Spring AOP(面向切面编程)组件的实现原理,包括Spring AOP的基础概念、动态代理模式、AOP组件的实现以及Spring选择JDK动态代理或CGLIB动态代理的依据。
Spring的AOP组件详解