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 ...
随机推荐
- 对HTML语义化的一些理解和记录
什么是HTML语义化 说HTML语义化就要先说说HTML到底负责的什么?下面摘自维基百科: 超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页 ...
- JavaWeb中登录验证码生成
1.页面代码 <html> <head> <title>Title</title> <script type="text/javascr ...
- 数组去重--hash方法
hash方法我以前百度找到的,经常用性能好速度快,本文章主要是一步步解释hash方法的过程(其实没多少步) 在这里就能看出每个自定义下标都是独一无二的,其实就相当于数组arr已经去重了 剩下我们就需要 ...
- MDI设置父子窗体
1.新建父窗体,设置窗体属性:IsMdicontainer设置成true; 2.拖入button控件,修改button中的text. 3.点击button控件设置代码: //1.窗体实例化 Form ...
- 为什么vue中的data用return返回呢?
不使用return包裹的数据会在项目的全局可见,会造成变量污染:使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件. 当一个组件被定义, data 必须声明为返回一个初始数据对象的函 ...
- python对接elasticsearch的基本操作
基本操作 #!/usr/bin/env python # -*- coding: utf-8 -*- # author tom from elasticsearch import Elasticsea ...
- 【python】提取sql语句中的表名
前言 最近刚学python,写一个小工具时需要提取sql语句中表名,查询一番后找到一篇文章挺不错的,mark一下 PS.那篇文章是转载的,且没有标注转载自哪里 正文 import ply.lex as ...
- WPF学习概述
引言 在桌面开发领域,虽然在某些领域,基于electron的跨平台方案能够为我们带来某些便利,但是由于WPF技术能够更好的运用Direct3D带来的性能提升.以及海量Windows操作系统和硬件资源的 ...
- 快速上手项目远程团队协作--CODING(新手向)
快速上手项目远程团队协作--CODING(新手向) CODING网址:https://e.coding.net/signin 前言:之前用过github,用过微软的Azure协作(https://az ...
- JAVA-阿里云短信服务
1.引入相关依赖 <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> < ...