本文主要介绍Spring中所支持的常用的扩展接口,Spring非常庞大且已成体系,众多的开发者包括Spring框架的开发者不可能随意改动框架原来来实现个性化的需求,所以提供了许多扩展接口,遵循开闭原则
开闭原则定义:一个软件实体。如类/模块/函都应该对扩展开放,对修改关闭。
BeanPostProcessor 族
BeanPostProcessor是Spring实现『开闭原则』的一大体现,Spring 会在启动的不同阶段调用不同的BeanPostProcessor实现类,而这些BeanPostProcessor实现类由开发者自行实现(也有许多Spring内置的BeanPostProcessor)来实现启动中的各类需求。
实现了BeanPostProcessor及其子类接口的Bean将会被BeanFactory在执行refresh中某些特殊阶段进行回调,可以在这些方法内部修改或添加类似BeanDefinition、创建Bean代理等操作。
很多Spring框架内部使用了BeanPostProcessor来实现一些功能,例如@Autowired功能是通过AutowiredAnnotationBeanPostProcessor来实现。
BeanPostProcessor
| 1 | public interface BeanPostProcessor { | 
postProcessBeforeInitialization
该方法将在Bean实例化完成,并注入完属性后被调用,但优先于init-method、InitializingBean#afterPropertiesSet和InitializingBean#afterPropertiesSet。
可以在该方法中返回包装对象或代理对象。
如果此方法返回null,那么后续的BeanPostProcessor将不会被调用。
postProcessAfterInitialization
该方法在postProcessBeforeInitialization、InitializingBean#afterPropertiesSet、init-method调用完成之后被调用。
可以在该方法中返回包装对象或代理对象。
如果此方法返回null,那么后续的BeanPostProcessor将不会被调用。
InstantiationAwareBeanPostProcessor
| 1 | public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { | 
postProcessBeforeInstantiation
该方法在实例化Bean之前调用,可以在此处返回代理对象。
如果该方法返回值不为null,那么其余的实例化操作将会被短路short-circuited,包括其余的InstantiationAwareBeanPostProcessor和实例属性的注入(populate),但是会执行所有的BeanPostProcessor#postProcessAfterInitialization。
postProcessAfterInstantiation
该方法在实例化Bean之后,注入属性之前被调用。
如果该方法返回true,那么后续的属性注入将被执行;如果返回false,那么将不执行属性的注入,也不会执行其他InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation方法。
该方法适合在自动注入属性前进行自定义字段的注入。
postProcessPropertyValues
该方法在postProcessAfterInstantiation方法调用之后,注入参数之前被调用,可以在此方法中添加或修改需要注入到Bean中的参数。
@Resource、@Autowire等注解就是在此处实现自动注入的,扫描对应字段的注解,并将获取到的参数值传入该方法返回值PropertyValues中,后续Spring 将自动把参数注入到对应的字段中。
如果该方法返回null,将不会执行属性的注入,也不会执行其他InstantiationAwareBeanPostProcessor#postProcessPropertyValues方法。
SmartInstantiationAwareBeanPostProcessor
| 1 | public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor { | 
predictBeanType
预测并返回Bean的实际类型,如果无法预测可以返回null,一般在BeanDefinition无法确定Bean类型时调用。
determineCandidateConstructors
在Bean实例化前被调用,用来确认实例化需要调用的构造方法候选列表。
如果返回不为null,那么不会执行其他的SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors,Spring将会在该返回列表中选择一个方法进行调用。如果所有的SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors均返回null,那么将使用默认的无参构造方法进行调用.
getEarlyBeanReference
出现循环依赖时将会被调用,通过此方法返回一个Bean的引用。
MergedBeanDefinitionPostProcessor
| 1 | public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor { | 
postProcessMergedBeanDefinition
该方法在合并完Bean定义后被调用。
例如AutowiredAnnotationBeanPostProcessor将在此处解析所有带@Autowire注解的参数。
BeanFactoryPostProcessor 族
BeanFactoryPostProcessor
| 1 | public interface BeanFactoryPostProcessor { | 
postProcessBeanFactory
该方法在所有BeanDefinition被加载完成后,Bean初始化之前被调用。
可以在此处修改已加载的BeanDefinition,或添加自定义的BeanDefinition,来实现动态注册Bean。
BeanDefinitionRegistryPostProcessor
| 1 | public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { | 
postProcessBeanDefinitionRegistry
该方法在所有BeanDefinition被加载完成后,BeanFactoryPostProcessor#postProcessBeanFactory之前被调用。
可以在此处修改已加载的BeanDefinition,或添加自定义的BeanDefinition,来实现动态注册Bean;也可以在此方法中注册其他BeanDefinitionRegistryPostProcessor,但如果当前Bean也是被其他BeanDefinitionRegistryPostProcessor#postProcessBeanFactory加载的,那么当前Bean加载的BeanDefinitionRegistryPostProcessor将没有机会被执行。
Aware 族
实现了Aware接口的Bean将会在特定的场景中被Spring回调,并传入对应的参数供Bean使用。
BeanNameAware
setBeanName
该方法在Bean实例化完成并注入属性后,BeanPostProcessor#postProcessBeforeInitialization方法前被调用。
Bean的名称将会从入参中被传入,该name可能会被添加例如#之类的前缀标识符,如果想要获得原始的name,可以调用BeanFactoryUtils#originalBeanName(String)。
BeanClassLoaderAware
setBeanClassLoader
该方法在Bean实例化完成并注入属性后,BeanPostProcessor#postProcessBeforeInitialization方法前被调用。
Bean的classLoader将会被传入。
BeanFactoryAware
setBeanFactory
该方法在Bean实例化完成并注入属性后,BeanPostProcessor#postProcessBeforeInitialization方法前被调用。
持有当前Bean的BeanFactory将会被传入。
EnvironmentAware
setEnvironment
该方法将被ApplicationContextAwareProcessor#postProcessBeforeInitialization调用,即在Bean实例化完成,并注入完属性后被调用,但优先于InitializingBean#afterPropertiesSet和init-method。
将从入参传入Environment
EmbeddedValueResolverAware
setEmbeddedValueResolver
该方法将被ApplicationContextAwareProcessor#postProcessBeforeInitialization调用,即在Bean实例化完成,并注入完属性后被调用,但优先于InitializingBean#afterPropertiesSet和init-method。
将从入参传入StringValueResolver
ResourceLoaderAware
setResourceLoader
该方法将被ApplicationContextAwareProcessor#postProcessBeforeInitialization调用,即在Bean实例化完成,并注入完属性后被调用,但优先于InitializingBean#afterPropertiesSet和init-method。
将从入参传入ResourceLoader
ApplicationEventPublisherAware
setApplicationEventPublisher
该方法将被ApplicationContextAwareProcessor#postProcessBeforeInitialization调用,即在Bean实例化完成,并注入完属性后被调用,但优先于InitializingBean#afterPropertiesSet和init-method。
将从入参传入ApplicationEventPublisher
MessageSourceAware
setMessageSource
该方法将被ApplicationContextAwareProcessor#postProcessBeforeInitialization调用,即在Bean实例化完成,并注入完属性后被调用,但优先于InitializingBean#afterPropertiesSet和init-method。
将从入参传入MessageSource
ApplicationContextAware
setApplicationContext
该方法将被ApplicationContextAwareProcessor#postProcessBeforeInitialization调用,即在Bean实例化完成,并注入完属性后被调用,但优先于InitializingBean#afterPropertiesSet和init-method。
将从入参传入ApplicationContext
Other
FactoryBean
| 1 | public interface FactoryBean<T> { | 
FactoryBean是一个定义工厂Bean的接口,如果一个Bean实现了这个接口,那么Spring在初始化的时候会创建该类型的实例,在通过该实例创建其对应的Bean。
FactoryBean有三个方法需要子类来实现
isSingleton方法用来返回当前FactoryBean创建的Bean是否为单例,如果返回true表示是单例(singleton)模式的Bean,如果返回false,表示是原型模式(prototype)的Bean。
getObjectType方法用来返回该FactoryBean将会创建的Bean的类型。
getObject方法返回创建的Bean,当Spring需要通过FactoryBean创建一个新的Bean的时候,将会调用FactoryBean#getObject来获取Bean并放入IOC容器中。
AbstractFactoryBean
AbstractFactoryBean继承自FactoryBean,提供了getObject方法的默认实现并添加了两个抽象方法需要子类实现。一般情况下,AbstractFactoryBean需要实现四个方法
isSingleton与FactoryBean中的isSingleton方法相同。
getObjectType与FactoryBean中的getObjectType方法相同。
createInstance与FactoryBean中的createInstance方法相同,即AbstractFactoryBean中不需要实现createInstance方法。
destroyInstance方法将在Bean被销毁前调用,用来手动处理Bean销毁前需要处理的工作,例如关闭资源等。
InitializingBean
| 1 | public interface InitializingBean { | 
实现了InitializingBean的Bean将在实例化完成后被回调,具体时机是Bean属性注入完成、BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三类Aware回调完成、BeanPostProcessor#postProcessBeforeInitialization调用完成之后,BeanPostProcessor#postProcessAfterInitialization之前。
此时,Bean已经基本初始化完成,此时可以在此方法内部做诸如参数校验、最终初始化等操作。
DisposableBean
| 1 | public interface DisposableBean { | 
实现了DisposableBean的Bean将在销毁前被回调。
可以在该方法内部做最后的清理工作,例如关闭资源等。
ApplicationRunner
| 1 | public interface ApplicationRunner { | 
Spring将在刷新完上下文之后,依次调用所有实现了ApplicationRunner接口Bean的’run’方法。
CommandLineRunner
| 1 | public interface CommandLineRunner { | 
Spring将在刷新完上下文之后,依次调用所有实现了CommandLineRunner接口Bean的run方法,与ApplicationRunner的差别是CommandLineRunner会将启动命令行中的参数传入run方法。
ApplicationListener
| 1 | public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { | 
实现ApplicationListener的Bean将在对应ApplicationEvent事件发生时被回调,对应的事件为ApplicationListener定义的类型参数,可以通过@EventListener实现类似效果。
可以通过ApplicationEventPublisher#publishEvent发布消息
Lifecycle
| 1 | public interface Lifecycle { | 
实现了Lifecycle接口的Bean,容器会在生命周期中的不同阶段回调对应的方法,可以在这些方法中执行特定的操作。
start会在容器启动的最后阶段被调用,具体时机是创建完所有的Bean之后,ContextRefreshedEvent消息广播、调用ApplicationRunner#run方法之前。一般情况下,Spring容器不会调用start()方法,所以Lifecycle#start不会被调用,所以需要使用SmartLifecycle。
stop会在容器关闭前被调用,具体时机是ContextClosedEvent消息广播之后,DisposableBean#destory方法调用之前。
isRunning用来返回当前Bean是否是运行中,如果返回true,那么不会执行start方法,会执行stop方法;如果返回false,那么会执行start方法,不会执行stop方法。
SmartLifecycle
SmartLifecycle在Lifecycle基础上实现了Phased类,可以用来控制不同SmartLifecycle的执行顺序,并且在容器进行刷新时也会调用start方法。
ImportBeanDefinitionRegistrar
| 1 | public interface ImportBeanDefinitionRegistrar { | 
该接口的作用类似与BeanDefinitionRegistryPostProcessor,可以在此处修改已加载的BeanDefinition,或添加自定义的BeanDefinition,来实现动态注册Bean;
不同于其他的组件只需要注入IOC容器即可被自动发现并被调用,BeanDefinitionRegistryPostProcessor子类需要通过@Import注解引入方可使用。
registerBeanDefinitions方法将会被ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry调用,ConfigurationClassPostProcessor是通过实现了BeanDefinitionRegistryPostProcessor接口而获得注册BeanDefinition的能力,所以被调用时机与BeanDefinitionRegistryPostProcessor一致。
各类接口调用时机
- BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
- BeanDefinitionRegistryPostProcessor#postProcessBeanFactory
- BeanFactoryPostProcessor#postProcessBeanFactory
- InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
- 创建Bean实例
- MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
- InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
- InstantiationAwareBeanPostProcessor#postProcessPropertyValues
- Bean属性注入
- BeanNameAware#setBeanName
- BeanClassLoaderAware#setBeanClassLoader
- BeanFactoryAware#setBeanFactory
- BeanPostProcessor#postProcessBeforeInitialization
- InitializingBean#afterPropertiesSet
- 执行init-method
- BeanPostProcessor#postProcessAfterInitialization
- Lifecycle#start
- ApplicationRunner#run
- CommandLineRunner#run
- 广播ContextRefreshedEvent