spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(01)
在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 = true;
//调用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
if (!continueWithPropertyPopulation) {
return;
}
上面这段逻辑就是来循环已经注册的beanPostProcessor,找到是InstantiationAwareBeanPostProcessor的类型,并执行其postProcessAfterInstantiation方法,通过查看已注册的beanPostProcessor发现其返回值均为true,通过上面的分析,只有postProcessAfterInstantiation方法返回false,populateBean方法才会返回,属性注入才会中断,即不会注入值。
怎么才能保证postProcessAfterInstantiation方法返回false那,这里只有自己向spring注册一个InstantiationAwareBeanPostProcessor的后置处理器,下面是我的一个后置处理器,
package cn.com.my.test; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("beanName:"+beanName);
if("userService".equals(beanName)) {
return false;
}
return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
}
}
自定义的beanPostProcessor仅实现了postProcessAfterInstantiation方法,上面的代码逻辑中,可以看到只有beanName为userService的时候,改方法才会返回false,其他情况下调用的接口方法,返回默认值true。
下面看我的测试类,
package cn.com.my.test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(Config.class);
UserService us=ac.getBean(UserService.class);
System.out.println("us.roleService:"+us.getRoleService());
}
}
下面是我的UserService类,
package cn.com.my.test; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component; @Component
public class UserService { @Autowired
private RoleService roleService; public RoleService getRoleService() {
return roleService;
} public void setRoleService(RoleService roleService) {
this.roleService = roleService;
}
}
从UserService类中,可以看出有一个加了注解的roleService属性,正常情况下会自动注入改属性,但在我自定义的beanPostProcessor之后,看下面的结果

神奇的事情,发生了us.roleService的属性返回的null。
这是为什么那,我们再看populateBean中的这段代码,
boolean continueWithPropertyPopulation = true;
//调用beanPostProcessors即bean后置处理器,
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
} if (!continueWithPropertyPopulation) {
return;
}
由于,我们向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之三:InitDestroyAnnotationBeanPostProcessor(01)
在<spring中BeanPostProcessor之二:CommonAnnotationBeanPostProcessor(01)>一文中,分析到在调用CommonAnnotationB ...
- spring中BeanPostProcessor之四:AutowiredAnnotationBeanPostProcessor(01)
在<spring中BeanPostProcessor之二:CommonAnnotationBeanPostProcessor(01)>中分析了CommonAnnotationBeanPos ...
- Spring中BeanPostProcessor
Spring中BeanPostProcessor 前言: 本文旨在介绍Spring动态配置数据源的方式,即对一个DataSource的配置诸如jdbcUrl,user,password,driverC ...
- spring中BeanPostProcessor之二:CommonAnnotationBeanPostProcessor(01)
在上篇博客中分享了InstantiationAwareBeanPostProcessor接口中的四个方法,分别对其进行了详细的介绍,在文末留下了一个问题,那就是postProcessPropertie ...
- spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(02)
在上篇博客中写道了bean后置处理器InstantiationAwareBeanPostProcessor,只介绍了其中一个方法的作用及用法,现在来看postProcessBeforeInstanti ...
- spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(03)
前面介绍了InstantiationAwareBeanPostProcessor后置处理器的postProcessBeforeInstantiation和postProcessAfterInstant ...
- spring(三):spring中BeanPostProcessor的使用
spring中实现BeanPostProcessor的后置处理器 ApplicationContextAwareProcessor 进入该实现类内部 可以看到:该类帮我们组建IOC容器,判断我们的be ...
- Spring中的BeanPostProcessor
一.何谓BeanProcessor BeanPostProcessor是SpringFramework里非常重要的核心接口之一,我先贴出一段源代码: /* * Copyright 2002-2015 ...
- 通过BeanPostProcessor理解Spring中Bean的生命周期
通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理 Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProces ...
随机推荐
- Chrome 63 - What"s New in DevTools(中文字幕)
大家好,这是代码之声(codefm)第一期,今天给大家带来的是 What's New In DevTools (Chrome 63). Chrome 一般会每隔 6 周发布一次主版本.目前 Chro ...
- safari坑之 回弹
博客地址: https://www.seyana.life/post/20 今天在使用safari浏览博客的时候, 发现在拉至顶部并产生回弹之后,头部导航隐藏了, 除非在上拉的时候,刚好达到顶部而不超 ...
- 关于使用map存放数据乱序”问题“
今天做项目中遇到了一个比较低级的错误,如果没注意将会变的更麻烦... 其实吧,也不难,要求就是将list中的值转为map后,再顺序输出map中的值,list的顺序怎样,加入到map的顺序也应怎样,不能 ...
- Android模拟器不能上网的解决方法
我原来一直不用Android的模拟器,因为这东西的多年前的印象真的是很糟糕——启动半个小时,不支持OpenGL.即使后来有了x86镜像,在HAXM的支持下快的飞起,也不想用,因为NDK还要编译x86的 ...
- vs远程调试iis
1.在开发电脑上 找到 D:\Software\VS2010\Common7\IDE\Remote Debugger 下面msvsmon.exe所在的两个文件夹x86和x64,使用x86或者x64是根 ...
- Python网络协议(osi七层协议)
一 互联网的本质 咱们先不说互联网是如何通信的(发送数据,文件等),先用一个经典的例子,给大家说明什么是互联网通信. 现在追溯到八九十年代,当时电话刚刚兴起,还没有手机的概念,只是有线电话,那么此时你 ...
- CSS每日学习笔记(2)
7.31.2019 1.CSS定位:允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素.另一个元素甚至浏览器窗口本身的位置. CSS 有三种基本的定位机制:普通流.浮动和绝对定位.除非专 ...
- Natas11 Writeup(常见编码、异或逆推、修改cookie)
Natas11: 页面提示cookie被异或加密保护,查看源码,发现了一个预定义参数和三个函数. //预定义参数,猜测将showpassword设置为yes即可得到密码. $defaultdata = ...
- python中可变长度参数详解
1. *args用法:python会将所有位置的参数收集到一个元组中 2. **args用法:python会将关键字参数传递给一个新的字典.**允许将关键字参数转换为字典 用法见如下代码: def f ...
- 环境篇:Virtualbox+Vagrant安装Centos7
环境篇:Virtualbox+Vagrant安装Centos7 1 安装Vagrant Vagrant下载地址:https://www.vagrantup.com/ Vagrant百度网盘:https ...