spring-BeanFactoryPostProcessor有什麼功能呢。他能改變bean在實例化之前的一些原註解值,比如單例變原型,手動減輕BeanFactory的工作壓力。
原註解是指spring默認爲bean裝配的註解比如:@Scope,@lazy,@Primary,@DependsOn,@Role,@Description
直接看代碼
定義一個單例bean
@Component
@Scope("singleton")
public class Teacher{
public Teacher(){
System.out.println("Construct");
}
@PostConstruct
public void init(){
System.out.println("init");
}
}
自定義實現該接口BeanFactoryPostProcessor的處理器
@Component
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("teacher");
beanDefinition.setScope("prototype");
System.out.println("Scope:"+beanDefinition.getScope());
}
}
這樣就完成的對於bean的作用域變化,但是這個地方是將自定義的TestBeanFactoryPostProcessor交給了spring管理
如果我們不想呢,當然如果瞭解@Import這個註解用法的人可能有個大膽的想法,通過自定義註解靈活開啓該處理器的功能。
首先我們去掉該類交給spring管理的註解@Component,添加自定義註解
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TestBeanFactoryPostProcessor.class)
public @interface TestBeanFactoryPostProcessorAnno {
}
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("teacher");
beanDefinition.setScope("prototype");
System.out.println("Scope:"+beanDefinition.getScope());
}
}
配置類添加我們的自定義註解來靈活開啓
@Configuration
//@Import(TestImportSelector.class)
//@TestImportSelectorAnno
@TestBeanFactoryPostProcessorAnno
@ComponentScan("org.springframework.test.main.*")
public class ScanConfig {
}
@Configuration這個註解加與不加程序一樣能完整跑下去,但是加與不加有什麼區別呢,我們後期再提。