BeanPostProcessor原理--使用讲解
《Spring源码解析》笔记
BeanPostProcessor原理学习
在学习BeanPostProcessor的原理学习完之后,对Spring如何使用充满好奇,尝试使用例子进行理解,以下记录过程:
1、使用ApplicationContextAware,可以指定,在当前函数中获取到容器上下文,具体使用举例如下:
@Component
public class Dog implements ApplicationContextAware { //@Autowired
private ApplicationContext context; public Dog(){
System.out.println("dog constructor...");
} @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// TODO Auto-generated method stub
this.context = applicationContext; } }
2、在Dog类中通过使用变量context即可获取Spring的容器上下文,但是具体如何实现?
ApplicationContextAware本身并没有继承BeanPostProcess,只继承Aware接口
public interface ApplicationContextAware extends Aware { /**
* Set the ApplicationContext that this object runs in.
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }
通过代码运行,可以看到调用,该setApplicationContext是通过类ApplicationContextAwareProcessor实现,
查看ApplicationContextAwareProcessor:
class ApplicationContextAwareProcessor implements BeanPostProcessor {}
当容器中的Bean赋值后,会遍历容器中的BeanPostProcessor ,挨个执行,自然会执行到ApplicationContextAwareProcessor 的postProcessBeforeInitialization()方法。
在其中执行的是this.invokeAwareInterfaces(bean)函数,查看invokeAwareInterfaces()函数代码:
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
} if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
} if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
} if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
} if (bean instanceof MessageSourceAware) {
((MessageSourceAware)bean).setMessageSource(this.applicationContext);
} if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
}
} }
3、从代码中可以看出
该函数只会执行实现Aware接口的Bean,我们的实现类Dog实现的是ApplicationContextAware
即会执行其相关的代码,自动为Dog中变量进行赋值。
4、引申学习Aware
自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;
把Spring底层一些组件注入到自定义的Bean中;
xxxAware:部分Aware接口的功能使用xxxProcessor;
ApplicationContextAware==》ApplicationContextAwareProcessor;
例如BeanNameAware接口的实现见4.3;
4.1 Aware的子接口如图所示:
4.2 举例Aware的使用方式
@Component
public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// TODO Auto-generated method stub
System.out.println("传入的ioc:"+applicationContext);
this.applicationContext = applicationContext;
}
@Override
public void setBeanName(String name) {
// TODO Auto-generated method stub
System.out.println("当前bean的名字:"+name);
}
//StringValueResolver:Resolve the given String value, for example parsing placeholders.
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
// TODO Auto-generated method stub
String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");
System.out.println("解析的字符串:"+resolveStringValue);
}
}
4.2 BeanNameAware接口的实现
首先在函数initializeBean中,会调用invokeAwareMethods函数,其中Beanpostprocess的两个方法及初始化方法都是在该函数中进行执行。
进入invokeAwareMethods函数
在函数中可以观察到部分Aware的子接口均是在此实现。
BeanPostProcessor原理--使用讲解的更多相关文章
- webpack与browser-sync热更新原理深度讲解
本文首发于CSDN网站,下面的版本又经过进一步的修订.原文:webpack与browser-sync热更新原理深度讲解本文包含如下内容: webpack-hot-middleware EventSou ...
- (转)linux下文件删除的原理精华讲解(考试题答案系列)
linux下文件删除的原理精华讲解(考试题答案系列) 说明:本文为老男孩linux培训某节课前考试试题及答案分享博文内容的一部分,也是独立成题的,你可以点下面地址查看全部的内容信息.http://ol ...
- 16、生命周期-BeanPostProcessor原理
16.生命周期-BeanPostProcessor原理 16.1 打断点运行postProcessBeforeInitialization 可以看到先执行的顺序为: applyBeanPostProc ...
- Gradle原理动画讲解(五)
Gradle原理动画讲解
- KMP的原理详细讲解
1.kmp算法的原理: 本部分内容转自:http://www.cnblogs.com/c-cloud/p/3224788.html及 http:// ...
- Servlet的生命周期以及简单工作原理的讲解
Servlet生命周期分为三个阶段: 1,初始化阶段 调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段 调用destr ...
- springboot(3)——配置文件和自动配置原理详细讲解
原文地址 目录 概述 1. 配置文件作用 2.配置文件位置 3.配置文件的定义 3.1如果是定义普通变量(数字 字符串 布尔) 3.2如果是定义对象.Map 3.3如果是定义数组 4.配置文件的使用 ...
- BeanPostProcessor原理学习
<Spring源码解析>笔记 1.自定义的BeanPostProcessor @Component public class MyBeanPostProcessor implements ...
- stl的实现原理简单讲解,通熟易懂
总结 需要经常随机访问请用vector 2.list list就是双向链表,元素也是在堆中存放,每个元素都是放在一块内存中,它的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随机存 ...
随机推荐
- chrony实现局域网时间同步
chrony基于cs架构实现,配置一台服务主机与其他客户主机即可 服务端 #yum install chrony --RHEL7默认已安装chrony,而没有安装ntpd. #systemctl st ...
- java 生成随机数字+字母组合 和字母组合
生成随机数包含数字,字母 /** * 生成随机数当作getItemID * n : 需要的长度 * @return */ private static String getItemID( int n ...
- Switch控制器
比如目前有qq和百度两个网站,switch可以指定选择一个 Switch value是填写索引值,从0开始.也可以书去请求的名词比如,qq或者百度 填写0就是访问qq 填写1就是访问百度
- jQuery方法-queue()
<!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8&quo ...
- Vuejs input 和 textarea 元素中使用 v-model 实现双向数据绑定
demo <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...
- php array remove empty values
print_r(array_filter($linksArray)); 參考 Remove empty array elements Remove Empty Array Elements In PH ...
- 【ZJOI2007】捉迷藏
题面 Description Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子. 某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏. 他们的家很大且构造很奇特,由N个屋子和N-1条 ...
- input 实现一次性上传文件
在实际项目中可能会用到,上传多个文件请求一次接口,因此,主要代码 $('#tabList').on('click','.resetWorkStatus',function(){ var that = ...
- SQLServer2008上的SDE备份和还原
一.备份 右键数据库>任务>备份.选择完整模式,导出为xxx.bak文件即可. 二.还原 1.创建sde用户名,新建同名数据库xxx,并指定sde为xxx的拥有者. 2.在master上创 ...
- 19. 接口(创建interface 继承implements)
1.语法: interface 接口名{ 属性 抽象方法 } 2.实例: 3.注意: 1)类实现接口可以通过implements实现,实现接口的时候必须把接口中的所有方法实现,一个类可以实现多个接口. ...