【Spring】Spring后置处理器

Spring经过XML解析获取到了所有需要实例化Bean的信息并读取到BeanDefinition后,就保存在了BeanDefinitionMap容器中。在实例化bean的操作就是依据这些BeanDefinition定义来做,而在实例化之前,Spring允许我们通过自定义扩展来改变bean的定义。定义一旦变了,后面的实例也就变了。而beanFactory后置处理器,既BeanFactoryPostProcessor就是用来改变bean定义的。

invokeBeanFactoryPostProcessors(beanFactory)

// 创建BeanFactory,并且把定义的Bean的信息读取到了BeanDefinition中
invokeBeanFactoryPostProcessors(beanFactory);

// BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor接口的调用
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

在加载完BeanDefinition后紧接着就会执行obtainFreshBeanFactory,帮我们调用实现了BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口的方法。

BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,所以它们一共有两个核心的方法:

@Component
public class WintigBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    /**
     * 在实例化之前,可以对BeanDefinition进行修改和注册
     * @param registry the bean definition registry used by the application context
     * @throws BeansException
     */
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

        // 获取所有beanDefinitionNames
        String[] beanDefinitionNames = registry.getBeanDefinitionNames();

        for (String beanDefinitionName : beanDefinitionNames) {
            // 根据name获取beanDefinition
            BeanDefinition beanDefinition = registry.getBeanDefinition(beanDefinitionName);
        }

        // 新增beanDefinition
        GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
        genericBeanDefinition.setBeanClass(GenericBeanDefinitionBean.class);
        // 属性设置
        MutablePropertyValues propertyValues = genericBeanDefinition.getPropertyValues();
        propertyValues.add("name", "wintig");
        registry.registerBeanDefinition("genericBeanDefinitionBean", genericBeanDefinition);

        // 删除指定beanDefinition
        registry.removeBeanDefinition("genericBeanDefinitionBean");

        // 自定义扫描器
        // 就完成了"com.wintig"路径下,有WintigService注解类的扫描
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
        scanner.addIncludeFilter(new AnnotationTypeFilter(WintigService.class));
        scanner.scan("com.wintig");
    }

    /**
     * 拿到beanFactory容器,你可以根据业务进行扩展
     * @param beanFactory the bean factory used by the application context
     * @throws BeansException
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory)beanFactory;
        // 允许使用相同名称重新注册不同的bean实现
        listableBeanFactory.setAllowBeanDefinitionOverriding(true);
        // 允许循环依赖
        listableBeanFactory.setAllowCircularReferences(true);
    }

    public class GenericBeanDefinitionBean {
        
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_25448409/article/details/111570794
今日推荐