概述
1.可扩展的接口启动调用顺序图
org.springframework.beans.factory.xxx
org.springframework.boot.xxx
org.springframework.context.xxx
- ApplicationContextInitializer.initialize
- AbstractApplicationContext.refresh
- BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry
- BeanDefinitionRegistryPostProcessor.postProcessBeanFactory
- InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
- SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors
- MergedBeanDefinitionPostProcessor.postProcessorMergedBeanDefinition
- InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
- SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
- BeanFactoryAware.setBeanFactory
- InstantiationAwareBeanPostProcessor.postProcessPropertyValues
- ApplicationContextAwareProcessor.invokeAwareInterfaces
- BeanNameAware.setBeanName
- InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization
- @PostConstruct
- InitiallzingBean.afterPropertiesSet
- InstantiationAwareBeanPostProcessor.postProcessAfterInitialization
- FactoryBean.getObject
- SmartInitilallzingSingleton.afterSingletonInstantiated
- CommondLineRunner.run
- 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内部有内置事件, 可以利用内置事件的监听器达到和前面一些触发点大致相同的事情。
- ContextRefreshedEvent: ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在ConfigurableApplicationContext接口中使用 refresh()方法来发生。
- ContextStartedEvent: ConfigurableApplicationContext.started()启动ApplicationContext, 发布事件。
- ContextStoppedEvent: ConfigurableApplicationContext.stopped()停止ApplicationContext, 发布事件。
- ContextClosedEvent: ConfigurableApplicationContext.closed()关闭ApplicationContext, 发布事件。
- RequestHandledEvent: web-specific 事件, 告诉所有Bean Http 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。当Spring处理用户请求结束后,系统会自动触发该事件。
最后
以上就是鲜艳耳机为你收集整理的SpringBoot 扩展性接口的全部内容,希望文章能够帮你解决SpringBoot 扩展性接口所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复