InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口,该接口的作用是感知Bean实例化的处理器。
该接口除了继承自父接口的两个方法外,还定义了三个方法

方法 描述
postProcessBeforeInstantiation
自身方法,是最先执行的方法,它在目标对象实例化之前调用,方法到的返回值是Object类型,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成对象的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInstantiation方法会调用,其他方法不调用;否则按照正常的流程走
postProcessAfterInstantiation
在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为他的返回值是决定要不要调用postProcessPropertyValues方法中的一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行
postProcessPropertyValues
对属性值进行修改,如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用,可以在该方法内对数性质进行修改
创建目标类
public class User{ private int id; private String name; private String beanName
; public User() { System.out.println("User被实例化..."); } public int getId() {
return id; } public void setId(int id) { this.id = id; } public String getName()
{ return name; } public void setName(String name) { System.out.println("设置:"+
name); this.name = name; } public String getBeanName() { return beanName; }
public void start() { System.out.println("自定义的初始化方法..."); } @Override public
StringtoString() { return "User [id=" + id + ", name=" + name + ", beanName=" +
beanName+ "]"; } }
自定义接口实现类
public class MyInstantiationAwareBeanPostProcessor implements
InstantiationAwareBeanPostProcessor { @Override public Object
postProcessBeforeInitialization(Object bean, String beanName) throws
BeansException{ System.out.println(">>>postProcessBeforeInitialization"); return
bean; } @Override public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException { System.out.println(
">>>postProcessAfterInitialization"); return bean; } @Override public Object
postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws
BeansException{ System.out.println("-->postProcessBeforeInstantiation"); return
null; } @Override public boolean postProcessAfterInstantiation(Object bean,
String beanName) throws BeansException { System.out.println(
"-->postProcessAfterInstantiation"); return true; } @Override public
PropertyValuespostProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[]
pds, Object bean, String beanName) throws BeansException { System.out.println(
"<**postProcessPropertyValues**>"); return pvs; } }
测试
public class Test { public static void main(String[] args) {
ClassPathXmlApplicationContext ac= new ClassPathXmlApplicationContext(
"applicationContext.xml"); User user = ac.getBean(User.class); System.out.
println(user); ac.registerShutdownHook(); } }

如果postProcessBeforeInstantiation方法返回了Object是null;那么就直接返回,调用doCreateBean方法();

如果postProcessBeforeInstantiation返回不为null;说明修改了bean对象;然后这个时候就立马执行postProcessAfterInitialization方法(注意这个是初始化之后的方法,也就是通过这个方法实例化了之后,直接执行初始化之后的方法;中间的实例化之后
和 初始化之前都不执行);

在调用postProcessAfterInitialization方法时候如果返回null;那么就直接返回,调用doCreateBean方法();(初始化之后的方法返回了null,那就需要调用doCreateBean生成对象了)

在调用postProcessAfterInitialization时返回不为null;那这个bean就直接返回给ioc容器了初始化之后的操作是这里面最后一个方法了;

总结:

InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置

postProcessBeforeInstantiation方法是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走

postProcessAfterInstantiation方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,
postProcessPropertyValues就会被执行

postProcessPropertyValues方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改

父接口BeanPostProcessor的2个方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目标对象被实例化之后,并且属性也被设置之后调用的

技术
©2020 ioDraw All rights reserved
(精华)2020年6月26日 C#类库 DataTable(扩展方法)解决CardLayout布局时按钮先执行方法,后切换页面 企业面对SEM竞价和SEO要如何取舍?还是两者都做?浙大数据结构期中考试试题程序(进程)在操作系统中是如何存储、分配空间的分享一场黑客帝国代码雨脚本,简单好玩!C++超级大神欢迎微软当爸爸:请缨重操旧业写游戏代码少儿编程孩子的学习路线django不关闭CSRF中间件,自定义通过CSRF检测的post请求centos7部署springboot jar包