如何查看spring源码
1.准备工作:在官网上下载了Spring源代码之后,导入Eclipse,以方便查询。
2.打开我们使用Spring的项目工程,找到Web.xml这个网站系统配置文件,在其中找到Spring的初始化信息:
listener
listener-classorg.springframework.web.context.ContextLoaderListener/listener-class
/listener
由配置信息可知,我们开始的入口就这里ContextLoaderListener这个监听器。
在源代码中我们找到了这个类,它的定义是:
public class ContextLoaderListener extends ContextLoader
implements ServletContextListener {
…
/**
* Initialize the root web application context.
*/
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
if (this.contextLoader == null) {
this.contextLoader = this;
}
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
...
}
该类继续了ContextLoader并实现了监听器,关于Spring的信息载入配置、初始化便是从这里开始了,具体其他阅读另外写文章来深入了解。
二、关于IOC和AOP
关于Spring IOC 网上很多相关的文章可以阅读,那么我们从中了解到的知识点是什么?
1)IOC容器和AOP切面依赖注入是Spring是核心。
IOC容器为开备银发者管理对象之间的依赖关系提供了便利和基础服务,其中Bean工厂(BeanFactory)和上下文(ApplicationContext)就是IOC的表现形式。BeanFactory是个接口类,只是对容器提供的最基本服务提供了定义,而DefaultListTableBeanFactory、XmlBeanFactory、ApplicationContext等都是具体的实现。
接口:
public interface BeanFactory {
//这里是对工厂Bean的转义定义,因为如果使用bean的名字检索IOC容器得到的对象是工厂Bean生成的对象,
//如果需要得到工厂Bean本身,需要使用转义的名字来向IOC容器检索
String FACTORY_BEAN_PREFIX = "";
//这里根据bean的名字,在IOC容器中得到bean实例,这个IOC容器就象一个大的抽象工厂,用户可以根据名字得到需要的bean
//在Spring中,Bean和普通的JAVA对象老前不同在于:
//Bean已经包含了我们在Bean定义信息中的依赖关系的处理,同时Bean是已经被放到IOC容器中进行管理了,有它侍滚清自己的生命周期
Object getBean(String name) throws BeansException;
//这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果根名字取得的bean实例的Class类型和需要的不同的话。
Object getBean(String name, Class requiredType) throws BeansException;
//这里提供对bean的检索,看看是否在IOC容器有这个名字的bean
boolean containsBean(String name);
//这里根据bean名字得到bean实例,并同时判断这个bean是不是单件,在配置的时候,默认的Bean被配置成单件形式,如果不需要单件形式,需要用户在Bean定义信息中标注出来,这样IOC容器在每次接受到用户的getBean要求的时候,会生成一个新的Bean返回给客户使用 - 这就是Prototype形式
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//这里对得到bean实例的Class类型
Class getType(String name) throws NoSuchBeanDefinitionException;
//这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
String[] getAliases(String name);
}
实现:
XmlBeanFactory的实现是这样的:
public class XmlBeanFactory extends DefaultListableBeanFactory {
//这里为容器定义了一个默认使用的bean定义读取器,在Spring的使用中,Bean定义信息的读取是容器初始化的一部分,但是在实现上是和容器的注册以及依赖的注入是分开的,这样可以使用灵活的 bean定义读取机制。
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
//这里需要一个Resource类型的Bean定义信息,实际上的定位过程是由Resource的构建过程来完成的。
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
//在初始化函数中使用读取器来对资源进行读取,得到bean定义信息。这里完成整个IOC容器对Bean定义信息的载入和注册过程
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws
BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
Spring源码解析(二)- 标签解析
默认标签的解析是在parseDefaultElement函数中进行,销弊函数中的功能分别对4中标签(import、alias、bean、beans)做了不同的解析。其中bean标签的解析最为复杂也最为重要。
默认的beanName初始为bean的id,若name存在为name,如果不存在beanName,那么根据Spring中提供的命名规则为当前bean生成对应的beanName.
用于属性承载的BeanDefinition是一个接口 ,在Spring中存在三种实现: RootBeanDefinition、ChildBean-Definition 以及 GenericBeanDefinition,三种实现均继承了AbstractBeanDefinition 。
其中 BeanDefinition 是 配置文件bean元素标签 在容器中的 内部表示形式 。bean元素标签拥有 class , scope , lazy-init 等配置属性,BeanDefinition则提供了相应的 beanClass , scope , lazyInit 属性,BeanDefinition和bean中的属性一一对应。
RootBeanDefinition是最为常用的实现类,对应一般性的bean标签; GenericBeanDefinition 是2.5版本加碰雀入的bean文件配置属性定义类,是一站式服务类。
解析默认标签中的自定义标签元素 ,首先是获取属性或者元素的命名空间,以此来判断该元素或者属性是否适用于自定义标签的解析条件,找出自定义类笑斗早型所对应的命名空间处理器并进行进一步的解析。自定义标签元素在默认标签中实际上就是属性。
BeanDefinition的注册分为两部分:beanName、别名。注册完成之后通知监听器已经注册完成。
在对bean进行定义时,除了使用id属性来指定名称,为了提供多个名称,可以使用alias标签来指定,所有名称都指向同一个bean。增加别名可以方便不同对象来调用。
import标签主要用于导入其他配置文件。
类似于import标签的解析,是递归调用beans的解析过程。
前言提到Spring根据命名空间来区分是默认标签与自定义标签。在很多情况下,我们需要为系统提供可配置化的支持,通过Spring提供的可扩展Schema的支持(XSD)来实现想要的配置。常见的自定义标签为事务标签(tx:annotation-driven)
Spring源码分析(一) XmlWebApplicationContext
spring是大家都会用的ioc框架,但是要真的了解spring还是需要好好研究一下才行,为此看了一些spring源码,所以开始写spring源码分析的文章,这个是第一篇,先从ioc容器的启动开始。
我们都御散知道,spring的ioc容器的最基本的接口就是BeanFactory,而ApplicationContext是包含了BeanFactory的所有信息,所以ioc容器在启动的时候就是从AbstractApplicationContext的refresh方法开始的
具体的启动流程就不说了,主要是这里有一个onRefresh方法,我们来看AbstractRefreshableWebApplicationContext这个类,在这个类中覆写了onRefresh方法
这是什么东西?别急,我们来看看themeSource是什么。
还是不太明白?那镇汪氏我们来看看AbstractRefreshableWebApplicationContext的结构
原来ThemeSource是一个接口,而AbstractRefreshableWebApplicationContext则实现了这个接口,在onRefresh把自己传进去了,好吧,这块就先看到这里。
我们直接到XmlWebApplicationContext这个类里,我们发现AbstractRefreshableApplicationContext类有一个方法loadBeanDefinitions,而XmlWebApplicationContext覆写了这个方法,我们来看看XmlWebApplicationContext是怎么实现的
这里我们要介绍ioc容器里的一个接口BeanDefinitionReader,而XmlBeanDefinitionReader是BeanDefinitionReader的一个实现类,负责对xml的配置文件进行读取,并放到ioc容器中。当读取完配置文件后,通过loadBeanDefinitions方法陵旅将bean注册到ioc容器中。
至此,ioc容器就启动完成。
XmlWebApplicationContext的分析就到这里了。