BeanFactoryPostProcessor
觸發時機是:**所有的 beanDefinition 收集完成,將要進行物件例項化的階段,這時可以修改 beanDefinition 或 新增 beanDefinition **
BeanFactoryPostProcessor 是個函式式介面,介面定義如下:
@FunctionalInterface
public interface BeanFactoryPostProcessor {
// ConfigurableListableBeanFactory 是 beanFactory 的子介面,所以可以拿到 beanDefinition
// 處於安全,不會讓你拿到所有 beanDefinition,只能透過特定條件拿指定的 beanDefinition,比如透過名稱
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
用法示例:修改 bean 的型別,原本是 UserDao,修改後成為 OrderDao
@Component
public class Test implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
// 假設配置了個bean,class 是 com.study.user.userDao,id 是 userDao
BeanDefinition userDao = configurableListableBeanFactory.getBeanDefinition("userDao");
// 把這個配置的 class 改為 com.study.order.orderDao
userDao.setBeanClassName("com.study.order.orderDao");
// 這時 ApplicationContext 獲取 userDao 實際就是 orderDao 了
}
}
用法示例:新增 beanDefinition
@Component
public class Test implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
// RootBeanDefinition 是 beanDefinition 子介面
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClassName("com.study.person.personDao");
// configurableListableBeanFactory 沒有註冊 beanDefinition 的方法,但是它的父類有
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
// beanDefinition 新增到 beanDefinitionMap 中
defaultListableBeanFactory.registerBeanDefinition("personDao", beanDefinition);
}
}
BeanDefinitionRegistryPostProcessor
是 BeanFactoryPostProcessor 的子介面,如果只是想單純增加 beanDefinition,這個更方便
介面定義:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
用法示例:
@Component
public class TestExtBeanDefinition implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 建立一個新的 BeanDefinition
BeanDefinition customBeanDefinition = BeanDefinitionBuilder
.rootBeanDefinition(CustomBean.class)
.getBeanDefinition();
// 將新的 BeanDefinition 註冊到 Spring 容器中
registry.registerBeanDefinition("customBean", customBeanDefinition);
}
}
BeanPostProcessor
觸發時機是:bean 的物件已經例項化,正在完善配置的階段
介面定義如下:
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
用法示例:修改 User 型別 的 bean 屬性 username
@Component
public class Test implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 如果 bean 是 User 才修改,不然所有的 bean 都要被修改
if (bean instanceof User){
System.out.println("BeanPostProcessor.before");
User userBean = (User) bean;
userBean.username = "張三";
// 返回修改後的 bean
return userBean;
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 同 postProcessBeforeInitialization 一樣,只不過這是最後步驟,一般也是 after 擴充套件居多
}
}