在spring中beanPostProcessor绝对是开天辟地的产物,给了程序员很多自主权,beanPostProcessor即常说的bean后置处理器。
一、概览先来说下InstantiationAwareBeanPostProcessor,这个后置处理器是BeanPostProcessor的子接口,继承自BeanPostProcessor,先看下BeanPostProcessor中的方法,
再看下InstantiationAwareBeanPostProcessor中的方法,
可见InstantiationAwareBeanPostProcessor扩展了BeanPostProcessor接口,并且新增了4个方法,今天先看postProcessAfterInstantiation方法,
default boolean postProcessAfterInstantiation(Object bean,String beanname) throws BeansException { return true; }
改方法有默认的返回值为true。
二、详述InstantiationAwareBeanPostProcessor中的postProcessAfterInstantiation方法的作用是什么那,用在什么地方。在看spring源码的时候看到属性注入这段代码,其中属性注入是在populateBean方法中完成,在此方法中便出现了postProcessAfterInstatiation方法的调用,这里只贴出populateBean方法中和这块有关系的代码,
boolean continueWithPropertyPopulation = ; //调用beanfactory中已注册的beanPostProcessors即bean后置处理器,判断是否为InstantiationAwareBeanPostProcessor的类型,如果是执行postProcessAfterInstantiation if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//如果返回值为false才会进到下面的赋值 *** 作,从而下方的1处才会为true,则属性注入才会中断 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanname)) { continueWithPropertyPopulation = false; break; } } } } //1 continueWithPropertyPopulation) { return; }
上面这段逻辑就是来循环已经注册的beanPostProcessor,找到是InstantiationAwareBeanPostProcessor的类型,并执行其postProcessAfterInstantiation方法,通过查看已注册的beanPostProcessor发现其返回值均为true,通过上面的分析,只有postProcessAfterInstantiation方法返回false,populateBean方法才会返回,属性注入才会中断,即不会注入值。
怎么才能保证postProcessAfterInstantiation方法返回false那,这里只有自己向spring注册一个InstantiationAwareBeanPostProcessor的后置处理器,下面是我的一个后置处理器,
package cn.com.my.test;import org.springframework.beans.BeansException; org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; org.springframework.stereotype.Component;@Componentpublic class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @OverrIDe Todo auto-generated method stub System.out.println("beanname:"+beanname); if("userService".equals(beanname)) { ; } return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean,beanname); }}
自定义的beanPostProcessor仅实现了postProcessAfterInstantiation方法,上面的代码逻辑中,可以看到只有beanname为userService的时候,改方法才会返回false,其他情况下调用的接口方法,返回默认值true。
下面看我的测试类,
org.springframework.context.annotation.AnnotationConfigApplicationContext;class Test { static voID main(String[] args) { Todo auto-generated method stub AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(Config.); UserService us=ac.getBean(UserService.); System.out.println("us.roleService:"+us.getRoleService()); }}
下面是我的UserService类,
org.springframework.beans.factory.annotation.autowired; org.springframework.stereotype.Component;@Component UserService { @autowired private RoleService roleService; public RoleService getRoleService() { roleService; } setRoleService(RoleService roleService) { this.roleService = roleService; }}
从UserService类中,可以看出有一个加了注解的roleService属性,正常情况下会自动注入改属性,但在我自定义的beanPostProcessor之后,看下面的结果
神奇的事情,发生了us.roleService的属性返回的null。
这是为什么那,我们再看populateBean中的这段代码,
; 调用beanPostProcessors即bean后置处理器, (InstantiationAwareBeanPostProcessor) bp; ; } } } } ; }
由于,我们向beanfactory中注册了一个beanPostProcessor,所以这里循环的时候肯定会执行我的postProcessAfterInstantiation后置处理器,而我在后置处理器中进行了判断,即在给beanname为userService进行属性注入的时候postProcessAfterInstantiation方法会返回false,那么上面的continueWithPropertyPopulation便为false,导致会进入到下面的if,方法直接返回,属性注入便会中止,所以UserService类中的roleService的值为null。
三、适用场合什么时候需要实现InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法那,如果不想使用spring的自动注入(前提是已经使用了@autowired注解),则对于特殊的bean则可以注册一个beanPostProcessor使其不进行注入,使用自己的方式进行注入。
原创不易,有不当之处,欢迎指正,谢谢!
总结
以上是内存溢出为你收集整理的spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(01)全部内容,希望文章能够帮你解决spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(01)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)