Spring源码扩展篇-BeanFactoryPostProcessor

spring容器初始化时,从资源中读取到bean的相关定义后,保存在beanFactory的成员变量中,在实例化bean的操作就是依据这些bean的定义来做的,而在实例化之前,spring允许我们通过自定义扩展来改变bean的定义,定义一旦变了,后面的实例也就变了,而beanFactory后置处理器,即BeanFactoryPostProcessor就是用来改变bean定义的;
 这里总结一下spring内部是怎么使用和加载的,具体源码就不展示了,比较复杂

1. ApplicationContext扩展类可以调用AbstractApplicationContext.addBeanFactoryPostProcessor方法,将自定义的BeanFactoryPostProcessor实现类保存到ApplicationContext中;
2. spring容器初始化时,上一步中被加入到ApplicationContext的bean会被优先调用其postProcessBeanFactory方法;
3. 自定义的BeanFactoryPostProcessor接口实现类,也会被找出来,然后调用其postProcessBeanFactory方法;
4. postProcessBeanFactory方法被调用时,beanFactory会被作为参数传入,自定义类中可以使用该参数来处理bean的定义,达到业务需求;
5. 此时的spring容器还没有开始实例化bean,因此自定义的BeanFactoryPostProcessor实现类不要做与bean实例有关的操作,而是 

 

下面可以简单介绍一下实际项目中怎么使用:

@Service("calculateService")
public class CalculateServiceImpl implements CalculateService {

    private String desc = "desc from class";

    public void setDesc(String desc) {
        this.desc = desc;
    }

    @Override
    public int add(int a, int b) {
        return a + b;
    }

    @Override
    public String getServiceDesc() {
        return desc;
    }
}

定义自定义的beanfactory后置处理器:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        AbstractBeanDefinition abstractBeanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("calculateService");

        MutablePropertyValues pv =  abstractBeanDefinition.getPropertyValues();
        pv.addPropertyValue("desc", "i am changed from bean factory post processor");
        abstractBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
    }
}

上述代码的功能很简单,找到名为”calculateService”的bean的定义对象,通过调用addPropertyValue方法,将定义中的desc属性值改为”Desc is changed from bean factory post processor”,这样等名为”calculateService”的bean被实例化出来后,其成员变量desc的值就是”Desc is changed from bean factory post processor”;可以看一下效果,此时此刻bean还没有被实例化
 

当然也可以像下面这样顶一个bean:

@Component
public class CompletStrategyBeanPostProccessor implements BeanFactoryPostProcessor {

    public final static String STRAREG_PACKAGE ="com.njdt.post.build.completion";

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        Map handlerMap = Maps.newHashMapWithExpectedSize(3);
        ClassFileScaner.scan(STRAREG_PACKAGE, CompletStrategyHandler.class).forEach(clazz ->{
            System.out.println(clazz);
            String type = clazz.getAnnotation(CompletStrategyHandler.class).name();
            handlerMap.put(type, clazz);
        });
//
//        Set> classSet = ClassFileScaner.scan(STRAREG_PACKAGE, CompletStrategyHandler.class);
//        Iterator> aa = classSet.iterator();
//        while (aa.hasNext()) {
//            String type = aa.getClass().getAnnotation(CompletStrategyHandler.class).name();
//            handlerMap.put(type, aa.getClass());
//        }


        CompletStrategyContext context = new CompletStrategyContext(handlerMap);
        //注册实例到spring容器中
        configurableListableBeanFactory.registerSingleton(CompletStrategyContext.class.getName(),context);
    }
}

上面是实现了把某个类型的标识和具体的实例进行了映射.

你可能感兴趣的:(Spring系列,spring,spring源码扩展)