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<String, Class> 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<Class<?>> classSet = ClassFileScaner.scan(STRAREG_PACKAGE, CompletStrategyHandler.class); // Iterator<Class<?>> 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); } }上面是实现了把某个类型的标识和具体的实例进行了映射.
