IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot 扩展性接口 -> 正文阅读

[Java知识库]SpringBoot 扩展性接口

1.可扩展的接口启动调用顺序图

org.springframework.beans.factory.xxx
org.springframework.boot.xxx
org.springframework.context.xxx
在这里插入图片描述

  1. ApplicationContextInitializer.initialize
  2. AbstractApplicationContext.refresh
  3. BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry
  4. BeanDefinitionRegistryPostProcessor.postProcessBeanFactory
  5. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
  6. SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors
  7. MergedBeanDefinitionPostProcessor.postProcessorMergedBeanDefinition
  8. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
  9. SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
  10. BeanFactoryAware.setBeanFactory
  11. InstantiationAwareBeanPostProcessor.postProcessPropertyValues
  12. ApplicationContextAwareProcessor.invokeAwareInterfaces
  13. BeanNameAware.setBeanName
  14. InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization
  15. @PostConstruct
  16. InitiallzingBean.afterPropertiesSet
  17. InstantiationAwareBeanPostProcessor.postProcessAfterInitialization
  18. FactoryBean.getObject
  19. SmartInitilallzingSingleton.afterSingletonInstantiated
  20. CommondLineRunner.run
  21. DisposableBean.destry

2.ApplicationContextInitializer

org.springframework.context.ApplicationContextInitializer

这是整个spring容器在刷新之前初始化ConfigurableApplicationContext的回调接口,简单来说,就是在容器刷新之前调用此类的initialize方法。这个点允许被用户自己扩展。用户可以在整个spring容器还没被初始化之前做一些事情。

可以想到的场景可能为,在最开始激活一些配置,或者利用这时候class还没被类加载器加载的时机,进行动态字节码注入等操作。

public class TestApplicationContextInitializer implements ApplicationContextInitializer {      
    @Override      
    public void initialize(ConfigurableApplicationContext applicationContext) {      
        System.out.println("[ApplicationContextInitializer]");      
    }      
}  

因为这时候spring容器还没被初始化,所以想要自己的扩展的生效,有以下三种方式:

  • 在启动类中用springApplication.addInitializers(new TestApplicationContextInitializer())语句加入

  • 配置文件配置context.initializer.classes=com.example.demo.TestApplicationContextInitializer

  • Spring SPI扩展,在spring.factories中加入org.springframework.context.ApplicationContextInitializer=com.example.demo.TestApplicationContextInitializer

3.BeanDefinitionRegistryPostProcessor

org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor

这个接口在读取项目中的beanDefinition之后执行,提供一个补充的扩展点

使用场景:你可以在这里动态注册自己的beanDefinition,可以加载classpath之外的bean

public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {      
    @Override      
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {      
        System.out.println("[BeanDefinitionRegistryPostProcessor] postProcessBeanDefinitionRegistry");      
    }      
      
    @Override      
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {      
        System.out.println("[BeanDefinitionRegistryPostProcessor] postProcessBeanFactory");      
    }      
}   

4.BeanFactoryPostProcessor

org.springframework.beans.factory.config.BeanFactoryPostProcessor

这个接口是beanFactory的扩展接口,调用时机在spring在读取beanDefinition信息之后,实例化bean之前。

在这个时机,用户可以通过实现这个扩展接口来自行处理一些东西,比如修改已经注册的beanDefinition的元信息

public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {      
    @Override      
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {      
        System.out.println("[BeanFactoryPostProcessor]");      
    }      
}      

5.InstantiationAwareBeanPostProcessor

org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor

继承了BeanPostProcessor, 而BeanPostProcessor只在bean的初始化阶段进行扩展, 而InstantiationAwareBeanPostProcessor接口则在初始化阶段, 实例化阶段和属性注入阶段

public class TestInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {      
      
    @Override      
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {      
        System.out.println("[TestInstantiationAwareBeanPostProcessor] before initialization " + beanName);      
        return bean;      
    }      
      
    @Override      
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {      
        System.out.println("[TestInstantiationAwareBeanPostProcessor] after initialization " + beanName);      
        return bean;      
    }      
      
    @Override      
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {      
        System.out.println("[TestInstantiationAwareBeanPostProcessor] before instantiation " + beanName);      
        return null;      
    }      
      
    @Override      
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {      
        System.out.println("[TestInstantiationAwareBeanPostProcessor] after instantiation " + beanName);      
        return true;      
    }      
      
    @Override      
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {      
        System.out.println("[TestInstantiationAwareBeanPostProcessor] postProcessPropertyValues " + beanName);      
        return pvs;      
    }      
  • postProcessBeforeInstantiation: 实例化bean之前,相当于new这个bean之前
  • postProcessAfterInstantiation: 实例化bean之后, 相当与new这个bean之后
  • postProcessPropertyValues: bean 已经实例化以后, 在属性注入阶段触发, @Autowired和@Resource基于此方法
  • postProcessBeforeInitialization: 初始化bean之前, 相当于把bean注入spring上下文之前
  • postProcessAfterInitialization: 初始化bean之后, 相当于把bean注入spring上下文之后

写中间件和业务中,都能利用这个特性。比如对实现了某一类接口的bean在各个生命期间进行收集,或者对某个类型的bean进行统一的设值等等。

6.SmartInstantiationAwareBeanPostProcessor

org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor

public class TestSmartInstantiationAwareBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor {      
      
    @Override      
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {      
        System.out.println("[TestSmartInstantiationAwareBeanPostProcessor] predictBeanType " + beanName);      
        return beanClass;      
    }      
      
    @Override      
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {      
        System.out.println("[TestSmartInstantiationAwareBeanPostProcessor] determineCandidateConstructors " + beanName);      
        return null;      
    }      
      
    @Override      
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {      
        System.out.println("[TestSmartInstantiationAwareBeanPostProcessor] getEarlyBeanReference " + beanName);      
        return bean;      
    }      
}
  • predictBeanType: 该触发点发生在postProcessBeforeInstantiation之前, 这个方法用于预测Bean的类型, 返回第一个预测成功的Class类型, 如果不能预测返回null。当你调用BeanFactory.getType(name)时当通过bean的名字无法得到bean类型信息时就调用该回调方法来决定类型信息。
  • determineCandidateConstructors: 该触发点发生在postProcessBeforeInstantiation之后, 用于确定bean的构造函数, 返回的是bean的所以构造函数列表, 可以通过此方法自定义选择对应的构造器来实例化bean
  • getEarlyBeanReference: 该触发点发生在postProcessAfterInstantiation之后, 当有循环依赖的场景,当bean实例化好之后,为了防止有循环依赖,会提前暴露回调方法,用于bean实例化的后置处理。这个方法就是在提前暴露的回调方法中触发。

7.BeanFactoryAware

org.springframework.beans.factory.BeanFactoryAware

发生在bean的实例化之后,注入属性之前,也就是Setter之前。这个类的扩展点方法为setBeanFactory,可以拿到BeanFactory这个属性。

public class TestBeanFactoryAware implements BeanFactoryAware {      
    @Override      
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {      
        System.out.println("[TestBeanFactoryAware] " + beanFactory.getBean(TestBeanFactoryAware.class).getClass().getSimpleName());      
    }      
} 

可以在bean实例化之后, 初始化之前, 拿到beanFactory, 然后对bean进行特殊化的定制, 或者将beanFactory拿到进行缓存, 日后使用。

8.ApplicationContextAwareProcessor

org.springframework.context.support.ApplicationContextAwareProcessor

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationStartupAware) {
			((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}

6个扩展点: EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, ApplicationStartupAware

9.BeanNameAware

org.springframework.beans.factory.BeanNameAware

public class NormalBeanA implements BeanNameAware{      
    public NormalBeanA() {      
        System.out.println("NormalBean constructor");      
    }      
      
    @Override      
    public void setBeanName(String name) {      
        System.out.println("[BeanNameAware] " + name);      
    }      
}

触发点为bean的初始化之前, postProcessBeforeInitialization方法之前, 可以通过在初始化bean之前拿到spring容器中注册的的beanName, 修改beanName。

10.@PostConstruct

javax.annotation.PostConstruct

public class NormalBeanA {      
    public NormalBeanA() {      
        System.out.println("NormalBean constructor");      
    }      
      
    @PostConstruct      
    public void init(){      
        System.out.println("[PostConstruct] NormalBeanA");      
    }      
}

触发点是在postProcessBeforeInitialization之后,InitializingBean.afterPropertiesSet之前。

11.InitializingBean

org.springframework.beans.factory.InitializingBean

初始化bean, 在方法postProcessAfterInitialization之前实现。

public class NormalBeanA implements InitializingBean{      
    @Override      
    public void afterPropertiesSet() throws Exception {      
        System.out.println("[InitializingBean] NormalBeanA");      
    }      
}

进行系统启动的时候一些业务指标的初始化工作

12.FactoryBean

org.springframework.beans.factory.FactoryBean

工厂Bean, Spring提供了70多个实现, 隐藏了复杂的bean的细节, 给上层提供了便利

public class TestFactoryBean implements FactoryBean<TestFactoryBean.TestFactoryInnerBean> {      
      
    @Override      
    public TestFactoryBean.TestFactoryInnerBean getObject() throws Exception {      
        System.out.println("[FactoryBean] getObject");      
        return new TestFactoryBean.TestFactoryInnerBean();      
    }      
      
    @Override      
    public Class<?> getObjectType() {      
        return TestFactoryBean.TestFactoryInnerBean.class;      
    }      
      
    @Override      
    public boolean isSingleton() {      
        return true;      
    }      
      
    public static class TestFactoryInnerBean{      
      
    }      
}      

可以通过这个类, 实例化bean作为一个代理, 比如为该对象的所以方法做一个拦截, 输出一个日志信息。

13.SmartInitializingSingleton

org.springframework.beans.factory.SmartInitializingSingleton

  • afterSingletonsInstantiated: 在spring容器管理的所有单例对象(非懒加载对象)初始化完成之后调用的回调接口。在postProcessAfterInitialization之后执行。
public class TestSmartInitializingSingleton implements SmartInitializingSingleton {      
    @Override      
    public void afterSingletonsInstantiated() {      
        System.out.println("[TestSmartInitializingSingleton]");      
    }      
}

可以对于所有单例对象初始化后, 做出一些业务处理

14.CommandLineRunner

org.springframework.boot.CommandLineRunner

run方法在触发时机为整个项目启动完毕后,自动执行。如果有多个CommandLineRunner,可以利用@Order来进行排序。

public class TestCommandLineRunner implements CommandLineRunner {      
      
    @Override      
    public void run(String... args) throws Exception {      
        System.out.println("[TestCommandLineRunner]");      
    }      
}

15.DisposableBean

org.springframework.beans.factory.DisposableBean

  • destroy: 对象销毁时执行。
public class NormalBeanA implements DisposableBean {      
    @Override      
    public void destroy() throws Exception {      
        System.out.println("[DisposableBean] NormalBeanA");      
    }      
}

16.ApplicationListener

org.springframework.context.ApplicationListener

可以监控某个事件, spring内部有内置事件, 可以利用内置事件的监听器达到和前面一些触发点大致相同的事情。

  1. ContextRefreshedEvent: ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在ConfigurableApplicationContext接口中使用 refresh()方法来发生。
  2. ContextStartedEvent: ConfigurableApplicationContext.started()启动ApplicationContext, 发布事件。
  3. ContextStoppedEvent: ConfigurableApplicationContext.stopped()停止ApplicationContext, 发布事件。
  4. ContextClosedEvent: ConfigurableApplicationContext.closed()关闭ApplicationContext, 发布事件。
  5. RequestHandledEvent: web-specific 事件, 告诉所有Bean Http 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。当Spring处理用户请求结束后,系统会自动触发该事件。
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:18:51  更:2022-10-17 12:20:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 -2025/2/1 15:54:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码