spring bean 扩展方式
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 扩展居多
}
}