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 扩展居多
    }

}

posted @ 2024-06-29 18:34  CyrusHuang  阅读(4)  评论(0编辑  收藏  举报