Spring IOC源码分析(一):ApplicationContext体系结构设计之自底向上分析
spring-context包
1. ApplicationContext接口
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver
最顶层接口,通过继承BeanFactory接口的方法,定义了与BeanFactory的关联绑定,以及其他功能组件,如Environment,MessageSource等的关联。
ApplicationContext是bean容器的一个运行环境,而实际的bean容器为内部绑定的BeanFactory,由BeanFactory来存放bean的元数据beanDefinitions,具体存放在BeanFactory的实现类的一个类型为ConcurrentHashMap的map中,其中key为beanName,value为BeanDefinition;以及bean实例的创建。
2. ConfigurableApplicationContext接口
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable
继承于ApplicationContext接口,提供与applicationListener,environment,beanFactoryProcessor等相关的get/set方法,还有启动入口方法refresh。
从ApplicationContext接口额外派生这个接口,而不是直接在ApplicationContext接口声明这些的原因:这些组件都是ApplicationContext接口的实现类在内部自身使用的,而ApplicationContext接口主要是定义对外的功能和方法声明,故在ConfigurableApplicationContext接口中声明这些方法,保证接口的清晰和职责的明确。
3. AbstractApplicationContext抽象类
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext
实现ConfigurableApplicationContext接口。
refresh方法:容器启动的骨架实现,使用了模板设计模式。提供对ConfigurableApplicationContext接口的refresh方法的模板实现,即定义了ApplicationContext的启动步骤,但是不提供具体每步的实现,由子类提供。
成员变量定义:定义了applicationListener,environment,beanFactoryProcessor等相关的成员变量。
4. AbstractRefreshableApplicationContext抽象类
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
implements BeanNameAware, InitializingBean
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext
FileSystemXmlApplicationContext:具体实现类,继承于AbstractXmlApplicationContext,指定从文件系统加载xml配置文件。
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry
继承于AbstractApplicationContext抽象类,故不具备上面的Config,Refreshable功能。而Bean的注册,是通过实现BeanDefinitionRegistry接口来提供往内部的beanFactory注入beanDefinitions,而beanDefinitions的来源则是通过BeanDefinitionParser解析,如xml文件来获取的。不支持重复调用refresh。例子如下:
GenericApplicationContext ctx = new GenericApplicationContext(); XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml")); PropertiesBeanDefinitionReader propReader = new PropertiesBeanDefinitionReader(ctx);
propReader.loadBeanDefinitions(new ClassPathResource("otherBeans.properties")); ctx.refresh();
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry
// 注册指定注解的类作为bean,如@Configuration,@Component等 /**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
使用包的数组作为构造函数参数,表示扫描这些包下面的类,将需要注册的类注册成bean。处理basePackages的包下面的@Component,以及派生的如@Service,@Controller,@Repository等,具体可以通过includeFilters和excludeFilters来配置需要哪些注解的类和排除哪些注解的类
/**
* Create a new AnnotationConfigApplicationContext, scanning for bean definitions
* in the given packages and automatically refreshing the context.
* @param basePackages the packages to check for annotated classes
*/
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
将ServletContext中的context-param的键值对数据,放到WebApplicationContext的environment中。servlet相关的则是servletConfig的init-param的键值对数据。
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
2.spring-mvc包的FrameworkServlet(或者是DispatcherServlet)所绑定WebApplicationContext为:即包含CONTEXT
/** Should we publish the context as a ServletContext attribute?. */
private boolean publishContext = true; protected WebApplicationContext initWebApplicationContext() { ... if (this.publishContext) {
// Publish the context as a servlet context attribute.
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
} return wac;
} /**
* Return the ServletContext attribute name for this servlet's WebApplicationContext.
* <p>The default implementation returns
* {@code SERVLET_CONTEXT_PREFIX + servlet name}.
* @see #SERVLET_CONTEXT_PREFIX
* @see #getServletName
*/
public String getServletContextAttributeName() {
return SERVLET_CONTEXT_PREFIX + getServletName();
} /**
* Prefix for the ServletContext attribute for the WebApplicationContext.
* The completion is the servlet name.
*/
public static final String SERVLET_CONTEXT_PREFIX = FrameworkServlet.class.getName() + ".CONTEXT.";
而作为一个servlet,在web容器中,通常会绑定一个servletConfig来指定该servlet的一些属性,如在web.xml配置这个servlet时,通过init-param标签来指定。所以在WebApplicationContext中,需要在DispatcherServlet绑定的WebApplicationContext中,将与DispatcherServlet绑定的servletConfig中相关的键值对数据,放到该WebApplicationContext的environment中。
如果是编程方式,则通常是从WebApplicationInitializer接口的实现类中指定并注入。

Spring IOC源码分析(一):ApplicationContext体系结构设计之自底向上分析的更多相关文章
- Spring Ioc源码分析系列--Ioc的基础知识准备
Spring Ioc源码分析系列--Ioc的基础知识准备 本系列文章代码基于Spring Framework 5.2.x Ioc的概念 在Spring里,Ioc的定义为The IoC Containe ...
- Spring Ioc源码分析系列--Ioc源码入口分析
Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...
- Spring IOC 源码分析
Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...
- Spring Ioc源码分析系列--前言
Spring Ioc源码分析系列--前言 为什么要写这个系列文章 首先这是我个人很久之前的一个计划,拖了很久没有实施,现在算是填坑了.其次,作为一个Java开发者,Spring是绕不开的课题.在Spr ...
- Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析
Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析 前言 上一篇文章Spring Ioc源码分析系列--Ioc源码入口分析已经介绍到Ioc容器 ...
- Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理
Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...
- Spring Ioc源码分析系列--Bean实例化过程(一)
Spring Ioc源码分析系列--Bean实例化过程(一) 前言 上一篇文章Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理已经完成了对 ...
- Spring Ioc源码分析系列--@Autowired注解的实现原理
Spring Ioc源码分析系列--@Autowired注解的实现原理 前言 前面系列文章分析了一把Spring Ioc的源码,是不是云里雾里,感觉并没有跟实际开发搭上半毛钱关系?看了一遍下来,对我的 ...
- Spring Ioc源码分析系列--自动注入循环依赖的处理
Spring Ioc源码分析系列--自动注入循环依赖的处理 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到Spring创建bean出现循环依赖的时候并没有深入去分 ...
随机推荐
- T1317:【例5.2】组合的输出
[题目描述] 排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数. 现要求你用递归的方法输出所有组 ...
- Struct和Union的sizeof计算
struct 结构体的大小不是简单的成员相加,要考虑存储空间的字节对齐 1.空结构体的大小为1 2.含有static的结构体在计算大小时不算上static变量,因为static存储在全局数据空间,而s ...
- js中函数的创建和调用都发生了什么?执行环境,函数作用域链,变量对象
博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/26/js%E4%B8%AD%E5%87%BD%E6%95%B0%E7%9A%84%E ...
- [已解决]报错:have mixed types. Specify dtype option on import or set low_memory=False
报错代码: import pandas as pd pd1 = pd.read_csv('D:/python34/program/wx_chat_single/qq_single.csv') 报错内容 ...
- The Accomodation of Students HDU - 2444 二分图判定 + 二分图最大匹配 即二分图-安排房间
/*655.二分图-安排房间 (10分)C时间限制:3000 毫秒 | C内存限制:3000 Kb题目内容: 有一群学生,他们之间有的认识有的不认识.现在要求把学生分成2组,其中同一个组的人相互不认 ...
- CTU OPEN 2017 Shooting Gallery /// 区间DP
题目大意: 给定n 给定n个数 选定一个区间留下其他消去 要求区间两端的两个数一样 若成功留下一个区间 则在选定区间的基础上 继续进行上述操作 直到无法再选出这样的区间 求最多操作数 按区间长度由短到 ...
- JS中Ajax的实现部分
2015-9-1 var url = "<%=servletName%>?user="+username.value+"&pwd="+pas ...
- Inversion of Control 控制反转 有什么好处
作者:Mingqi链接:https://www.zhihu.com/question/23277575/answer/169698662来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...
- 微信小程序の条件渲染
<view> 今天吃什么 </view> <view wx:if="{{condition==1}}">饺子</view> < ...
- shell同时输出多行信息