《Spring源码解析》笔记

BeanPostProcessor原理学习

在学习BeanPostProcessor的原理学习完之后,对Spring如何使用充满好奇,尝试使用例子进行理解,以下记录过程:

1、使用ApplicationContextAware,可以指定,在当前函数中获取到容器上下文,具体使用举例如下:

  1. @Component
  2. public class Dog implements ApplicationContextAware {
  3.  
  4. //@Autowired
  5. private ApplicationContext context;
  6.  
  7. public Dog(){
  8. System.out.println("dog constructor...");
  9. }
  10.  
  11. @Override
  12. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  13. // TODO Auto-generated method stub
  14. this.context = applicationContext; } }

2、在Dog类中通过使用变量context即可获取Spring的容器上下文,但是具体如何实现?

ApplicationContextAware本身并没有继承BeanPostProcess,只继承Aware接口

  1. public interface ApplicationContextAware extends Aware {
  2.  
  3. /**
  4. * Set the ApplicationContext that this object runs in.
  5. * Normally this call will be used to initialize the object.
  6. * <p>Invoked after population of normal bean properties but before an init callback such
  7. * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
  8. * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
  9. * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
  10. * {@link MessageSourceAware}, if applicable.
  11. * @param applicationContext the ApplicationContext object to be used by this object
  12. * @throws ApplicationContextException in case of context initialization errors
  13. * @throws BeansException if thrown by application context methods
  14. * @see org.springframework.beans.factory.BeanInitializationException
  15. */
  16. void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
  17.  
  18. }

通过代码运行,可以看到调用,该setApplicationContext是通过类ApplicationContextAwareProcessor实现,

查看ApplicationContextAwareProcessor:

  1. class ApplicationContextAwareProcessor implements BeanPostProcessor {}

当容器中的Bean赋值后,会遍历容器中的BeanPostProcessor ,挨个执行,自然会执行到ApplicationContextAwareProcessor 的postProcessBeforeInitialization()方法。

在其中执行的是this.invokeAwareInterfaces(bean)函数,查看invokeAwareInterfaces()函数代码:

  1. private void invokeAwareInterfaces(Object bean) {
  2. if (bean instanceof Aware) {
  3. if (bean instanceof EnvironmentAware) {
  4. ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
  5. }
  6.  
  7. if (bean instanceof EmbeddedValueResolverAware) {
  8. ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
  9. }
  10.  
  11. if (bean instanceof ResourceLoaderAware) {
  12. ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
  13. }
  14.  
  15. if (bean instanceof ApplicationEventPublisherAware) {
  16. ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
  17. }
  18.  
  19. if (bean instanceof MessageSourceAware) {
  20. ((MessageSourceAware)bean).setMessageSource(this.applicationContext);
  21. }
  22.  
  23. if (bean instanceof ApplicationContextAware) {
  24. ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
  25. }
  26. }
  27.  
  28. }

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的使用方式

  

  1. @Component
  2. public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
  3. private ApplicationContext applicationContext;
  4. @Override
  5. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  6. // TODO Auto-generated method stub
  7. System.out.println("传入的ioc:"+applicationContext);
  8. this.applicationContext = applicationContext;
  9. }
  10. @Override
  11. public void setBeanName(String name) {
  12. // TODO Auto-generated method stub
  13. System.out.println("当前bean的名字:"+name);
  14. }
  15. //StringValueResolver:Resolve the given String value, for example parsing placeholders.
  16. @Override
  17. public void setEmbeddedValueResolver(StringValueResolver resolver) {
  18. // TODO Auto-generated method stub
  19. String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");
  20. System.out.println("解析的字符串:"+resolveStringValue);
  21. }
  22. }

4.2 BeanNameAware接口的实现

首先在函数initializeBean中,会调用invokeAwareMethods函数,其中Beanpostprocess的两个方法及初始化方法都是在该函数中进行执行。

进入invokeAwareMethods函数

在函数中可以观察到部分Aware的子接口均是在此实现。

BeanPostProcessor原理--使用讲解的更多相关文章

  1. webpack与browser-sync热更新原理深度讲解

    本文首发于CSDN网站,下面的版本又经过进一步的修订.原文:webpack与browser-sync热更新原理深度讲解本文包含如下内容: webpack-hot-middleware EventSou ...

  2. (转)linux下文件删除的原理精华讲解(考试题答案系列)

    linux下文件删除的原理精华讲解(考试题答案系列) 说明:本文为老男孩linux培训某节课前考试试题及答案分享博文内容的一部分,也是独立成题的,你可以点下面地址查看全部的内容信息.http://ol ...

  3. 16、生命周期-BeanPostProcessor原理

    16.生命周期-BeanPostProcessor原理 16.1 打断点运行postProcessBeforeInitialization 可以看到先执行的顺序为: applyBeanPostProc ...

  4. Gradle原理动画讲解(五)

    Gradle原理动画讲解  

  5. KMP的原理详细讲解

    1.kmp算法的原理: 本部分内容转自:http://www.cnblogs.com/c-cloud/p/3224788.html及                           http:// ...

  6. Servlet的生命周期以及简单工作原理的讲解

    Servlet生命周期分为三个阶段: 1,初始化阶段              调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段           调用destr ...

  7. springboot(3)——配置文件和自动配置原理详细讲解

    原文地址 目录 概述 1. 配置文件作用 2.配置文件位置 3.配置文件的定义 3.1如果是定义普通变量(数字 字符串 布尔) 3.2如果是定义对象.Map 3.3如果是定义数组 4.配置文件的使用 ...

  8. BeanPostProcessor原理学习

    <Spring源码解析>笔记 1.自定义的BeanPostProcessor @Component public class MyBeanPostProcessor implements ...

  9. stl的实现原理简单讲解,通熟易懂

    总结 需要经常随机访问请用vector 2.list list就是双向链表,元素也是在堆中存放,每个元素都是放在一块内存中,它的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随机存 ...

随机推荐

  1. 只用200行Go代码写一个自己的区块链!(转)

    区块链是目前最热门的话题,广大读者都听说过比特币,或许还有智能合约,相信大家都非常想了解这一切是如何工作的.这篇文章就是帮助你使用 Go 语言来实现一个简单的区块链,用不到 200 行代码来揭示区块链 ...

  2. 3306端口被占用导致MySQL无法启动

    报错:mysql服务无法启动1067 发现WINDOWS下面没有MYSQL的服务在MYSQL的安装目录bin下面安装MYSQL服务:C:\Program Files\MySQL\MySQL Serve ...

  3. tty - 显示连接标准输入的终端的文件名

    总览 (SYNOPSIS) tty [OPTION]... 描述 (DESCRIPTION) 显示 连接 标准输入 的 终端 的 文件名. -s, --silent, --quiet 什么 都 不显示 ...

  4. 从零开始搭建系统1.1——CentOs安装

    本篇主要是记录安装CentOs的过程,为什么会选择CentOs,没有过多的原因,主要是出于CentOs相对来说安装的人比较多, 以后有问题了方便查资料.本次安装是安装在一台笔记本上,WIN7+Cent ...

  5. 笔记43 Spring Security简介

    基于Spittr应用 一.Spring Security简介 Spring Security是为基于Spring的应用程序提供声明式安全保护的安全 性框架.Spring Security提供了完整的安 ...

  6. C:\Windows\System32\drivers\etc中的hosts文件

    这个文件是根据TCP/IP for Windows 的标准来工作的,它的作用是包含IP地址和Host name(主机名)的映射关系,是一个映射IP地址和Host name(主机名)的规定,规定要求每段 ...

  7. mysql和postgresql查询数据库中哪些表包含某个字段

    想知道数据库中哪表含有edu_status字段   mysql> select table_name,column_name from information_schema.columns wh ...

  8. openwrt usb

    fdisk -l #以列表的形式,列出当前挂载盘的情况 for 属性规定 label 与哪个表单元素绑定 <form> <label for="male"> ...

  9. 最大字段和--GSS1 MUSHROOM ORZ

    过于naive了= =作为一个知识点总结一下算了.主要就是合并.对于一个区间的最大字段和,可以分别事下面的两个区间的子段和,或者事左边的右边加右边的左边.然后搞一下 = = #include < ...

  10. NX二次开发-UFUN设置环境变量UF_set_variable

    NX9+VS2012 #include <uf.h> #include <stdio.h> UF_initialize(); //UFUN方式 //设置环境变量 int a = ...