在Spring框架中最重要的是Spring IoC容器,它是Spring框架的核心。本文将从更高的角度来解析Sping IoC容器,了解其是如何设计的。了解一样东西最好的办法是从其核心本质出发,只要把握住了这样一个核心,其他的一些东西也迎刃而解了。这是一个很好的开端,我们一起开始吧...
Spring IoC容器
org.springframework.context.ApplicationContext
接口代表Spring IoC容器,主要负责bean的实例化、配置、装配,简而言之,Spring IoC容器是管理这些bean的(这里所说的bean指的是组成你的应用程序中的对象,并且这些对象被Spring所管理)。容器如何知道哪些对象要进行实例化、配置和装配的呢?是通过读取配置文件元数据来达到这个效果的,配置文件元数据是用xml配置、Java注解和Java代码配置来表示的。这使得作为程序员的我们,只需要向Spring容器提供配置元数据,Spring容器就能在我们的应用中实例化、配置和装配这些对象。org.springframework.beans
和org.springframework.context
包是Spring IoC容器的基础。Spring提供了很多Application
接口的实现。在单独的应用中,创建ClassPathXmlApplicationContext
和FileSystemXmlApplicationContext
的实例是非常常用的做法。示例如下:
<pre class="java" style="margin: 10px 0px; padding: 0px; white-space: pre !important; overflow-wrap: break-word; position: relative !important; color: rgb(49, 70, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
Copy
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); Hello hello = (Hello) ac.getBean("hello"); hello.sayHello();
</pre>
然而在大部分的应用场景中,不需要实例化一个或者多个Spring IoC容器的实例。例如在web应用的场景下,只需要在web.xml中创建七行样板配置的代码如下:
<pre class="xml" style="margin: 10px 0px; padding: 0px; white-space: pre !important; overflow-wrap: break-word; position: relative !important; color: rgb(49, 70, 89); font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
Copy
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</paramvalue> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
</pre>
下面这张图从更高的视角展示了Spring是怎样工作的。你的应用程序中的类是和配置元数据组合在一起,以便在ApplicationContext
创建和初始化之后,你拥有了一个完全配置的、可执行的系统。
image
ApplicationContext设计解析
为了方便对ApplicationContext
接口的层次结构有一个大概的认识,下面使用IDEA来生成ApplicationContext
的继承关系图。(选中ApplicationContext接口->右键->Diagrams->Show Diagrams...)
(温馨提示:点击图片可以查看高清大图)
image
从上图就能很清楚的看出ApplicationContext
继承的接口分为五类:
BeanFactory
:提供了能够管理任何对象的高级配置机制,这个接口是Spring框架中比较重要的一个接口。ListableBeanFactory
:从该接口的名字就能知道,该接口除了拥有BeanFactory的功能外,该接口还有能列出factory中所有bean的实例的能力。HierarchicalBeanFactory
:该接口除了拥有BeanFactory的功能外,还提供了BeanFactory分层的机制,查找bean的时候,除了在自身BeanFactory查找外,如果没有查找到,还会在父级BeanFactory进行查找。
MessageSource
:消息资源的处理,用于国际化。ApplicationEventPublisher
:用于处理事件发布机制。EnvironmentCapable
:提供了Environment
的访问能力。ResourceLoader
:用于加载资源的策略接口(例如类路径下的资源、系统文件下的资源等等)。ResourcePatternResolver
:用于将位置模式(例如Ant风格的路径模式)解析成资源对象的策略接口。classpath*:
前缀能匹配所以类路径下的资源。
先看一下在ApplicationContext
中定义的方法:
<pre class="java" style="margin: 10px 0px; padding: 0px; white-space: pre !important; overflow-wrap: break-word; position: relative !important; color: rgb(49, 70, 89);