2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。
需求:我们的需求是,在spring初始化完毕时,使我们自定义一个类Bird类可以得到spring容器内容。
实现步骤:
1.首先我们来看一下ApplicationContextAwareProcessor这个类,它是BeanPostProcessor(后置处理器)的一个实现类。所以ApplicationContextAwareProcessor里面也必定有后置处理器接口的两个前置和后置方法。
我们来看一下ApplicationContextAwareProcessor的前置方法:由前面讲解的后置处理器(链接:https://www.cnblogs.com/WNof11020520/p/10598745.html)可知,所有bean对象初始化前都会执行BeanPostProcessor接口实现类的前置方法postProcessBeforeInitialization,所以所有bean对象初始化前都会执行ApplicationContextAwareProcessor的postProcessBeforeInitialization方法。
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if(System.getSecurityManager() != null && (bean instanceof EnvironmentAware ||
bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware ||
bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware ||
bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
} if(acc != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareInterfaces(bean);
return null;
}, acc);
} else {
this.invokeAwareInterfaces(bean);
} return bean;
} 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);
}
} }
2.看以上代码第9、15、19、48行可知,假若bean对象的类是ApplicationContextAware类型的话,就会调用invokeAwareInterfaces方法,然后执行第48行,将spring容器赋值给bean对象的applicationContext属性。
所以重要的实现思路来了:
a.Bird类实现ApplicationContextAware接口,并添加一个ApplicationContext类型的属性context,并实现ApplicationContextAware接口的方法:
@Component
public class Bird implements ApplicationContextAware {
//得到管理它的Spring容器
private ApplicationContext context; @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
} @Override
public String toString() {
return "Bird [context=" + context + "]";
}
}
b.写一个测试类,测试结果:
public class TestMain {
public static void main(String[] args) {
// 1.获得Spring容器对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
System.out.println("Spring容器 " + context);
Bird bird = (Bird) context.getBean("bird");
System.out.println(bird);
}
}
c.查看测试输出的结果:输出结果显示,TestMain 类的main方法中new出来的context和Bird组件的bean对象的context属性地址相同,所以Bird的bean对象得到了spring容器内容。
"C:\Program Files\Java\jdk1.8.0_25\bin\java" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:52099,suspend=y,server=n -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_25\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar;D:\kaikeba_java\2018-11-28-spring-beanpostprocessor\02-项目\11_Spring_BeanPostProcessor的实现类介绍\target\test-classes;D:\kaikeba_java\2018-11-28-spring-beanpostprocessor\02-项目\11_Spring_BeanPostProcessor的实现类介绍\target\classes;D:\caowenlong\javaDevelopTool\apache-maven-3.5.3-bin\repo\org\springframework\spring-context\5.0.5.RELEASE\spring-context-5.0.5.RELEASE.jar;D:\caowenlong\javaDevelopTool\apache-maven-3.5.3-bin\repo\org\springframework\spring-aop\5.0.5.RELEASE\spring-aop-5.0.5.RELEASE.jar;D:\caowenlong\javaDevelopTool\apache-maven-3.5.3-bin\repo\org\springframework\spring-beans\5.0.5.RELEASE\spring-beans-5.0.5.RELEASE.jar;D:\caowenlong\javaDevelopTool\apache-maven-3.5.3-bin\repo\org\springframework\spring-core\5.0.5.RELEASE\spring-core-5.0.5.RELEASE.jar;D:\caowenlong\javaDevelopTool\apache-maven-3.5.3-bin\repo\org\springframework\spring-jcl\5.0.5.RELEASE\spring-jcl-5.0.5.RELEASE.jar;D:\caowenlong\javaDevelopTool\apache-maven-3.5.3-bin\repo\org\springframework\spring-expression\5.0.5.RELEASE\spring-expression-5.0.5.RELEASE.jar;D:\caowenlong\javaDevelopTool\IntelliJ IDEA 2016.2\lib\idea_rt.jar" com.kkb.test.TestMain
Connected to the target VM, address: '127.0.0.1:52099', transport: 'socket'
三月 26, 2019 11:26:26 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2ed94a8b: startup date [Tue Mar 26 11:26:26 CST 2019]; root of context hierarchy
Spring容器 org.springframework.context.annotation.AnnotationConfigApplicationContext@2ed94a8b: startup date [Tue Mar 26 11:26:26 CST 2019]; root of context hierarchy
Bird [context=org.springframework.context.annotation.AnnotationConfigApplicationContext@2ed94a8b: startup date [Tue Mar 26 11:26:26 CST 2019]; root of context hierarchy]
Disconnected from the target VM, address: '127.0.0.1:52099', transport: 'socket' Process finished with exit code 0
2.spring源码-BeanPostProcessor后置处理之ApplicationContextAwareProcessor,实现spring容器中某一个类的bean对象在初始化时需要得到Spring容器内容。的更多相关文章
- 1.spring源码-BeanPostProcessor后置处理器
1.BeanPostProcessor接口的介绍: BeanPostProcessor是一个接口,其中有两个方法,postProcessBeforeInitialization和postProcess ...
- Spring源码情操陶冶-ComponentScanBeanDefinitionParser文件扫描解析器
承接前文Spring源码情操陶冶-自定义节点的解析,本文讲述spring通过context:component-scan节点干了什么事 ComponentScanBeanDefinitionParse ...
- Spring源码解析之ConfigurationClassPostProcessor(二)
上一个章节,笔者向大家介绍了spring是如何来过滤配置类的,下面我们来看看在过滤出配置类后,spring是如何来解析配置类的.首先过滤出来的配置类会存放在configCandidates列表, 在代 ...
- Spring 源码学习
spring最核心的理念是IOC,包括AOP也要屈居第二,那么IOC到底是什么呢,四个字,控制反转 一.什么是Ioc/DI? IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等等. 先从我们 ...
- spring源码学习(一)
由于本人水平有限,本文内容较为简单,仅供个人学习笔记,或者大家参考,如果能够帮助大家,荣幸之至!本文主要分析AnnotationConfigApplicationContext实例化之后,到底干了那些 ...
- Spring源码解读Spring IOC原理
一.什么是Ioc/DI? IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等等. 先从我们自己设计这样一个视角来考虑: 所谓控制反转,就是把原先我们代码里面需要实现的对象创建.依赖的代码,反 ...
- Spring源码系列 — Bean生命周期
前言 上篇文章中介绍了Spring容器的扩展点,这个是在Bean的创建过程之前执行的逻辑.承接扩展点之后,就是Spring容器的另一个核心:Bean的生命周期过程.这个生命周期过程大致经历了一下的几个 ...
- Spring源码笔记
Spring Version:5.1.12 ApplicationContext 常用的实例化方式: ClassPathXmlApplicationContext FileSystemXmlAppli ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
随机推荐
- 原创: idea 的maven 方式配置 开发javaWeb(idea+tomcat +maven
通过idea 编辑器来配置基于maven创建站点,在tomcat上配置 在采用idea 配置之前,首先要确保maven和 tomcat 正确运行. maven 配置链接 tomcat 配置链接 实际你 ...
- Bash脚本编程学习笔记04:测试命令test、状态返回值、位置参数和特殊变量
我自己接触Linux主要是大学学习的Turbolinux --> 根据<鸟哥的Linux私房菜:基础篇>(第三版) --> 马哥的就业班课程.给我的感觉是这些课程对于bash的 ...
- maven 3.6.3 安装及配置
1.下载 下载地址:http://maven.apache.org/download.cgi 2.配置环境变量 解压压缩包到磁盘. 注意:各种系统配置环境变量位置不一样,已windows10为例. 我 ...
- docker搭建环境积累
weblogic12搭建 sudo docker pull ismaleiva90/weblogic12 sudo docker run -d -p : -p : ismaleiva90/weblog ...
- 【Android休眠】之Android休眠机制
一.休眠概述 休眠,简而言之就是设备在不需要工作的时候把一些部件.外设关掉(掉电或让它进入低功耗模式). 为什么要休眠呢?一言以蔽之:省电. 休眠分主动休眠和被动休眠.主动休眠:比如我电脑不用了,就通 ...
- 安装Docker到CentOS(YUM)
运行环境 系统版本:CentOS Linux release 7.3.1611 (Core) 软件版本:Docker 17.12.1-ce 硬件配置:无 安装过程 1.配置YUM-Docker存储库 ...
- python中的__dict__和dir()的区别
Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案. __dict__与dir()的区别: dir()是一个函数,返回的是list: __di ...
- Android学习笔记(一)
目录 Android学习笔记(一) 一.JDK.Android SDK 二.部分项目结构 三.字符串引用 四.外层build.gradle详解 五.app->build.gradle详解 六.日 ...
- Wannafly Camp 2020 Day 1D 生成树 - 矩阵树定理,高斯消元
给出两幅 \(n(\leq 400)\) 个点的无向图 \(G_1 ,G_2\),对于 \(G_1\) 的每一颗生成树,它的权值定义为有多少条边在 \(G_2\) 中出现.求 \(G_1\) 所有生成 ...
- 在 myeclipse 引入项目
1.进入 myeclipse 在界面空白处,右键,出现如下图所示 2.选择 Import...,弹出如下图所示界面 3.双击上图红框内的内容,弹出如下图所示界面,然后点击按钮“Browse...”,选 ...