之前都是说了怎么配置bean以及用法之类的,这篇博文来介绍下spring容器内幕。

内部容器工作机制

Spring中AbstractApplicationContext抽象类的refresh()方法是用来刷新Spring的应用上下文的。

@Override
public void refresh() throws BeansException, IllegalStateException {
//初始化BeanFactory
prepareBeanFactory(beanFactory);
//调用工厂后处理器
invokeBeanFactoryPostProcessors(beanFactory);
//注册bean后处理器
registerBeanPostProcessors(beanFactory);
//初始化消息源
initMessageSource();
//初始化应用上下文事件广播器
initApplicationEventMulticaster();
//初始化其他特殊的bean,由具体子类实现
onRefresh();
//注册事件监听器
registerListeners();
//初始化所有单实例的bean,使用懒加载模式的bean除外
finishBeanFactoryInitialization(beanFactory);
//完成刷新并发布容器刷新事件
finishRefresh();
}

直接看图解吧:

使用外部属性文件

项目中经常有很多配置,例如数据源相关数据、日志相关数据,按照习惯,大部分喜欢配置在properties文件中,那么在项目中如何使用这些属性呢?

jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost/mysqldb?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=round;

jdbc.username=root

jdbc.password=123456

applicationContext.xml

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:com/ty/jdbc.properties"/> <bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"> <property name="driverClassName"value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}"/> <property name="password"value="${jdbc.password}" /> </bean>

不过这种写法略显麻烦,看下另外一种写法:

<context:property-placeholder location="classpath:com/ty/jdbc.properties""/>
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"> <property name="driverClassName"value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}"/> <property name="password"value="${jdbc.password}" /> </bean>

注:location中的路径用“/”分隔。

不过这种也不是很方便,来看下最推荐的写法:

@Component
public class DataSource() {
@Value("${jdbc.driverClassName}")
private String driverClassName; @Value("${jdbc.url}")
private String url; @Value("${jdbc.username}")
private String username; @Value("${jdbc.password}")
private String password;
}

引用bean的属性值

当一个bean需要引用另外一个bean的属性值的时候,也可以这么写:

@Component
public class ApplicationManager() {
@Value("#{sysConfig.sessionTimeout}")
private int sessionTimeout; @Value("#{sysConfig.maxTabPageNum}")
private int maxTabPageNum;
}

spring容器事件

applicationContext能够发布事件以及允许注册相应的事件监听器,事件很好理解,就是当容器中出现了什么操作的时候,比如服务器启动、关闭,各个组件需要去怎么做。事件监听器则是负责监听这个事件的发生,来看下事件体系图:

  • 事件源:事件的产生者,任何一个EventObject都必须拥有一个事件源。
  • 事件监听器注册表:容器中有很多事件监听器,事件监听器注册表就是存放所有事件监听器的容器,然后容器统一来管理此注册表。
  • 事件广播器:事件产生后,由事件广播器将事件通知给事件监听器。

1、applicationEvent

2、ApplicationListener

3、事件广播器

4、spring事件体系

5、示例

测试一下:

sendMail方法中,首先创建了一个MailSendEvent,然后调用applicationContext.publishEvent(event)方法将事件发送给所有的事件监听器(内部机制就是基于事件广播器)。因为sendMail中需要用到applicationContext上下文,因此MailSender实现了ApplicationContextAware接口。另外applicationContext在初始化的时候提供了一个默认的事件广播器(用户也可自定义),然后applicationContext根据反射机制,将容器中所有实现了ApplicationListener接口的bean注册到事件监听器注册表中。

spring深入学习(三)-----spring容器内幕的更多相关文章

  1. Spring Boot 项目学习 (三) Spring Boot + Redis 搭建

    0 引言 本文主要介绍 Spring Boot 中 Redis 的配置和基本使用. 1 配置 Redis 1. 修改pom.xml,添加Redis依赖 <!-- Spring Boot Redi ...

  2. Spring Cloud 学习 之 Spring Cloud Eureka(源码分析)

    Spring Cloud 学习 之 Spring Cloud Eureka(源码分析) Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 ...

  3. Spring Cloud 学习 之 Spring Cloud Eureka(搭建)

    Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 文章目录 搭建服务注册中心: 注册服务提供者: 高可用注册中心: 搭建服务注册中心: ...

  4. spring深入学习(一)-----IOC容器

    spring对于java程序员来说,重要性不可言喻,可以想象下如果没有他,我们要多做多少工作,下面一个系列来介绍下spring(5.x版本). spring模块 IOC概念 spring中最重要的两个 ...

  5. Spring.Net学习笔记(1)-容器的使用

    一.下载地址: http://www.springframework.net/download.html 二.相关程序集 Spring.Net容器定义在程序集Spring.Core.dll中,它依赖于 ...

  6. Spring Cloud学习笔记--Spring Boot初次搭建

    1. Spring Boot简介 初次接触Spring的时候,我感觉这是一个很难接触的框架,因为其庞杂的配置文件,我最不喜欢的就是xml文件,这种文件的可读性很不好.所以很久以来我的Spring学习都 ...

  7. Spring 框架学习(1)--Spring、Spring MVC扫盲

    纸上得来终觉浅,绝知此事要躬行 文章大纲 什么是spring 传统Java web应用架构 更强的Java Web应用架构--MVC框架 Spring--粘合式框架 spring的内涵 spring核 ...

  8. Spring框架学习03——Spring Bean 的详解

    1.Bean 的配置 Spring可以看做一个大型工厂,用于生产和管理Spring容器中的Bean,Spring框架支持XML和Properties两种格式的配置文件,在实际开发中常用XML格式的配置 ...

  9. Spring框架学习02——Spring IOC 详解

    1.Spring IOC的基本概念 IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理.当某个Java对象(调用者)需要调用 ...

随机推荐

  1. GDI+_VB6_ARGB

    在写一个用GDI+代替VB的Line函数的方法时,遇到了一个问题. GdipCreateSolidFill 参数 color [in]ARGB颜色,指定此实体画笔的初始颜色. brush [out]指 ...

  2. python的apidoc使用

    一.apidoc的安装 npm install apidoc -g -g参数表示全局安装,这样在哪儿都能使用. 二.apidoc在python接口代码中的使用 def index(): "& ...

  3. Hbase--知识点总结3

    Hbase知识点总结:  hbase表中为什么列族的数量不能太多? 因为当一个列族数据溢写的时候,其他列族也会发生数据溢写,但是其他列族中数据的数量还没有达到溢写的阈值,就会导致产生的小文件数量增多. ...

  4. 大数据入门到精通15--hive 对 date类型的处理

    一.基础日期处理 //date 日期处理select current_date;select current_timestamp;//to_date(time) ;to_date(string)sel ...

  5. 使用Log4J收集日志

    一:搭建好Selenium+testNG+Maven环境,可参考 http://www.cnblogs.com/hc1020/p/8602863.html 二:百度搜索Maven仓库,然后搜索Log4 ...

  6. 阿里云-CentOS如何挂载硬盘

    阿里云CentOS挂载硬盘 查看当前未挂载的硬盘 # fdisk -l 创建硬盘分区 # fdisk /dev/vdb 根据提示,依次输入"n","p" &qu ...

  7. nginx屏蔽ip配置

    屏蔽单个IP的命令是 deny 192.168.201.1 封ip段192 deny 192.0.0.0/8 封ip段192.168 deny 192.168.0.0/16 封ip段192.168.2 ...

  8. hashCode 与 equals

    面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?”   hashCode()介绍 hashCode() 的作用是获取哈希码, ...

  9. python_Tkinter

    Tkinter相关 python支持多种图形界面的第三方库,包括:TKwxWidgetsQTGTK等等但是python自带的库是支持TK的TKinter,使用使用Tkinter,无需安装任何包,就可以 ...

  10. 2019-04(2)Python学习

    一.元组 1.什么是元组? 元组是一个固定长度,不可改变的Python序列对象.创建元组的最简单方式,是用逗号分隔一列值: In [1]: tup = 4, 5, 6 In [2]: tup Out[ ...