1、Spring 扩展点的执行顺序
1.1、Spring 扩展点
1.1.1、BeanFactoryPostProcessor
Bean 工厂后置处理器,主要用于加载 Spring 中的 BeanDefinition。
方法
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
可以使用 beanFactory 进行 Bean 的 BeanDefinition 定义与修改。
Spring 中元素加载情况: 项目中所有的 BeanDefinition 已被加载,但是普通 Bean 还未被实例化和初始化。
禁止事项
1、禁止过早初始化 Bean,初始化后 BeanPostProcessor 的实现类将不能处理当前 Bean,比如最常见的动态代理后置处理器,也就是说当前的 Bean 会代理失效。举个粟子,不能这样->
代码语言:java复制public class TestBean {
}
@Component
public class TestPostProcess implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.registerSingleton("testBean",new TestBean());
}
}
当然,如果你就是不需要被 BeanPostProcessor 处理,这个可以不用理会。
2、禁止使用依赖注入,因为当前普通 Bean 还未被创建,对象不会注入,调用的值将会是 null。
代码语言:less复制@Component
public class TestBean {
}
@Component
public class TestPostProcess implements BeanFactoryPostProcessor {
@Autowired
private TestBean testBean;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 这里将会输出 null
System.out.println(testBean);
}
}
实现类调用处: org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
1.1.2、BeanDefinitionRegistryPostProcessor
继承于 BeanFactoryPostProcessor 类,新增 postProcessBeanDefinitionRegistry 方法。
新增方法
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
扫描添加项目中的 BeanDefinition。
Spring 中元素加载情况: 项目中所有的 BeanDefinition 已被加载,但是普通 Bean 还未被实例化和初始化。
禁止事项
1、禁止使用 BeanDefinitionRegistryPostProcessor 的实现类注册 BeanDefinitionRegistryPostProcessor 实现类,这样被注册的 BeanDefinitionRegistryPostProcessor【postProcessBeanDefinitionRegistry】方法将不会执行。比如不能这样 ->
代码语言:java复制@Component
public class TestBean1DefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor , PriorityOrdered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.registerSingleton("testBeanDefinitionRegistryPostProcessor",new TestBeanDefinitionRegistryPostProcessor());
}
@Override
public int getOrder() {
return 1;
}
}
public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("我不会执行");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
实现类调用处: org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
使用技巧
代码语言:java复制@Component
public class TestBean1DefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor , PriorityOrdered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
registry.registerBeanDefinition("testBean",new RootBeanDefinition(TestBean.class));
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.registerSingleton("testBeanDefinitionRegistryPostProcessor",new TestBeanDefinitionRegistryPostProcessor());
}
@Override
public int getOrder() {
return 1;
}
}
1.1.3、BeanPostProcessor
Bean 的后置处理器,常用与对 Bean 的一些加工处理,比如最常见的动态代理。
方法
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
可以对 Bean 进行处理,比如替换等操作。
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
可以对 Bean 进行处理,比如替换等操作。
Spring 中元素加载情况: 项目中所有的 Bean 已创建,Bean 的属性已被自动装配。初始化方法还未被调用。
禁止事项
1、注意使用 registerBeanDefinition 注册 Bean,使用 registerBeanDefinition 注册 Bean 后,Bean 的初始化方法将会在 Bean 实际调用时执行。例如依赖注入,在依赖注入的地方会走 doGetBean 进而去进行实例创建和初始化。
代码语言:typescript复制@Component
public class TestBean {
@Autowired
private TestBean1 testBean1;
@PostConstruct
public void init(){
System.out.println(666);
System.out.println(testBean1);
}
}
public class TestBean1 {
@PostConstruct
public void init(){
System.out.println(333);
}
}
@Component
public class TestPostProcessor implements BeanPostProcessor {
@Autowired
private BeanFactory beanFactory;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) this.beanFactory;
String registerBeanName = "testBean1";
if (!beanDefinitionRegistry.containsBeanDefinition(registerBeanName)) {
beanDefinitionRegistry.registerBeanDefinition(registerBeanName, new RootBeanDefinition(TestBean1.class));
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
2、禁止使用 registerSingleton 注册 Bean,否则 Bean 的初始化方法不会得到执行,同样后置处理器也不会处理当前 Bean。具体原因我会在依赖注入中分析。这里先得出结果:由于使用当前方法注册的 Bean 实例已经有了,所以不会走创建实例和依赖注入,所以也就不会走初始化方法了。
代码语言:typescript复制@Component
public class TestPostProcessor implements BeanPostProcessor {
@Autowired
private BeanFactory beanFactory;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
ConfigurableListableBeanFactory beanDefinitionRegistry = (ConfigurableListableBeanFactory) this.beanFactory;
String registerBeanName = "testBean1";
if (!beanDefinitionRegistry.containsBean(registerBeanName)) {
beanDefinitionRegistry.registerSingleton(registerBeanName, new TestBean1());
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
3、禁止使用依赖注入普通 Bean,这样会导致 Bean 提前初始化而让后置处理器不再处理当前 Bean。
代码语言:typescript复制@Component
public class TestPostProcessor implements BeanPostProcessor {
@Autowired
private TestBean1 testBean1;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
或者
代码语言:typescript复制@Configuration
public class TestConfig {
@Bean
public TestPostProcessor testPostProcessor(TestBean1 testBean1){
return new TestPostProcessor();
}
}
最经典的反例就是 Shiro 框架中的这个配置:
代码语言:text复制 @Bean
public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm);
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
securityManager.setSubjectDAO(subjectDAO);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
shiroFilterFactoryBean.setFilters(filters);
shiroFilterFactoryBean.setFilterChainDefinitionMap(new HashMap<>());
return shiroFilterFactoryBean;
}
如果在 ShiroRealm 中依赖注入了对象,那么相关的代理会全部失效,也就是事务回滚会失效,注意注意!
请在 BeanFactoryPostProcessor 中注册 Bean。如果实现想要使用那么可以考虑在需要注入的 Bean 上标注 @Lazy 注解。当然如果你不在意以上缺点的话请忽略这些禁止项。
实现类调用处: org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization与org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
1.1.4、自定义的init方法
Bean 初始化方法。可以在 Bean 定义中指定初始化方法 @Bean(initMethod = "initMethod")
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata#invokeInitMethods
。
Spring 中元素加载情况: 已经实例化和依赖注入,在 InitDestroyAnnotationBeanPostProcessor 中 postProcessBeforeInitialization 调用,其实现 PriorityOrdered,order = 2147483647
1.1.5、@PostConstruct 注解标注的方法
Bean 初始化方法。
调用处:org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization
1.1.6、Aware
通过实现 Aware 的各种实现类可以获取 Spring 内部的一些资源,比如 BeanFactoryAware、EnvironmentAware。Spring 将会以回调的方式注入各种资源。
代码语言:java复制@Component
public class TestBeanFactoryAware implements BeanFactoryAware {
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
beanFactory.getBean("testBean");
}
}
1.1.7、SmartInitializingSingleton
所有 Bean 实例化、初始化、并被所有后置处理器处理后的一个扩展点
方法
void afterSingletonsInstantiated();
实现类调用处: org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
1.2、扩展点执行顺序
BeanFactoryPostProcessor(内部的执行顺序请参考www.nblogs.cn/doc/spring/…)
====>
BeanPostProcessor 的 postProcessBeforeInitialization、BeanPostProcessor 的 postProcessAfterInitialization(其中初始化方法在他们里面执行)
====>
SmartInitializingSingleton的afterSingletonsInstantiated
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!