Spring框架提供了各種PostProcessor的接口,作爲容器或者Bean的後置處理器,其實這些PostProcessor本省也是需要註冊到容器總的bean,裏面定義的方法會在特定的時期唄容器所調用。
通過這種機制框架自身或者開發者再不改變容器或者Bean核心邏輯的的情況下對進行擴展或者定義。 比如包裝Bean,影響他的行爲,修改他的內容。
PostProcessor的種類
1.BeanDefinitionRegistryPostProcessor
即BeanDefinitionRegistry的後置處理器
2.BeanFactoryPostProcessor
簡單容器的後置處理器
3.BeanPostProcessor
BeanDefinitionRegistryPostProcessor
根據註釋說明,可以在正常的BeanFactoryPostProcessor檢測之前註冊更多的 BeanDefinition
測試
@Configuration
public class CustomizedBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//多註冊一個user的Bean
Class<User> userClass = User.class;
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(userClass);
GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
registry.registerBeanDefinition("divUser",definition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
然後運行啓動類
是可以獲取到User的。
因此我們可以利用這種能力,去實現搜索某些第三方的class,然後註冊進容器裏面,MyBatis就是這麼做的。
BeanFactoryPostProcessor
根據註釋可以明白,主要影響容器裏面的行爲。
BeanPostProcessor
@Configuration
public class CustomizedBeanPostProcessor implements BeanPostProcessor {
//Bean初始化之前調用
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName+"調用了postProcessBeforeInitialization");
return bean;
}
//初始化之後
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName+"調用了"+"postProcessAfterInitialization");
return bean;
}
}
這樣子寫了之後,再容器初始化每個Bean的時候,都會處理這樣的邏輯。
因此我們可以利用這個能力對Bean包裝一些通用的邏輯包裝。這不就是AOP嗎?