Spring容器原理及源码学习
一、基本原理
在我看来,Spring的IOC容器,可以看作是一个Map,我们把我们的bean实例交给他管理,同时由它来管理各个实例的引用关系。需要使用的客户端直接获取实例就行。
二、IOC容器启动时的加载过程
明白了它的原理之后,我们来看看容器启动时是如何进行初始化的。
1. org.springframework.web.context.ContextLoaderListener
- 首先我们都会在项目中的web.xml配置一个监听器(ServletContextListener的实现),这个监听器将会在web容器启动时启动。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- ContextLoaderListener除了是监听器外,继承了ContextLoader,所以监听器启动时调用ContextLoader的initWebApplicationContext方法进行Spring的WebApplicationContext上的初始化工作。
// 继承了ContextLoader
public class ContextLoaderListener extends ContextLoader implements ServletContextListener
//启动时调用
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
if (this.contextLoader == null) {
this.contextLoader = this;
}
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
- initWebApplicationContext方法
//初始化后的Context放在这个成员域。这里可能会说到单例问题,后面会讲到refresh方法加了同步锁。
private WebApplicationContext context;
//校验是否已经存在,如果不存在实例化一个Context
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);
}
//实例化具体哪个实现类,在determineContextClass方法中进行决定。可以通过在web.xml中指定<context-param>的param指定contextClass。实际有默认策略,配置在spring-web-4.3.10.RELEASE.jar!\org\springframework\web\context\ContextLoader.properties文件内。
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
//得到的类名为 org.springframework.web.context.support.XmlWebApplicationContext
Class<?> contextClass = determineContextClass(sc);
//初始化Context的主要入口
configureAndRefreshWebApplicationContext(cwac, servletContext);
//将初始化后的值放回servletContext org.springframework.web.context.support.XmlWebApplicationContext.ROOT
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
- configureAndRefreshWebApplicationContext
配置文件的解析和容器的初始化
- 通过Environment初始化properties
- 实例化 ApplicationContextInitializer
- 调用refresh
org.springframework.web.context.ContextLoader#configureAndRefreshWebApplicationContext
//1. 读取properties文件
ConfigurableEnvironment env = wac.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
}
//2. 实例化 ApplicationContextInitializer
customizeContext(sc, wac);
//3. 主要下面要讲的容器初始化
wac.refresh();
2. 初始化容器refresh()
- 主要流程基本在这个方法,所以这里也是着重要介绍的。
- 整个过程是加锁的
org.springframework.context.support.AbstractApplicationContext#refresh
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//① Prepare this context for refreshing.
prepareRefresh();
//② Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//③ Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
//④ Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//⑤ Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//⑥ Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//⑦ Initialize message source for this context.
initMessageSource();
//⑧ Initialize event multicaster for this context.
initApplicationEventMulticaster();
//⑨ Initialize other special beans in specific context subclasses.
onRefresh();
//⑩ Check for listener beans and register them.
registerListeners();
//⑾ Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//⑿ Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
}
}
}
① prepareRefresh()
这是第一步为初始化做准备,记录启动时间、active标记、init和验证properties(上面也提到过,区别是什么这一次传入了servletConifig只是替换与之相关的一些默认值)
org.springframework.context.support.AbstractApplicationContext#prepareRefresh
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
② obtainFreshBeanFactory()
获得一个BeanFactory,这里是真正的对所有配置文件中的及其他一些配置的加载。BeanFactory真正存放着所有的bean定义信息及单示例。
1. 刷新BeanFactoery读取配置的bean:refreshBeanFactory
org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
protected final void refreshBeanFactory() throws BeansException {
//1.如果已经存在销毁
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//2.直接new一个DefaultListableBeanFactory实例
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//3.设置两个属性:allowBeanDefinitionOverriding,allowCircularReferences
//spring 3.29中多了这一行beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
customizeBeanFactory(beanFactory);
//4. 从xml配置文件中加载bean的定义信息BeanDefinitions放到beanFactory。实际每个bean有一个对应的beanDfinitions,里面存放了bean的属性,比如是否单例等等。
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
}
}
- loadBeanDefinitions(beanDefinitionReader);
读取configLocations中配置的applicationContext配置文件
org.springframework.web.context.support.XmlWebApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
//还记得在web.xml中配置的configLocations,就是在这遍历调用。
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
reader.loadBeanDefinitions(configLocation);
}
}
}
- doLoadBeanDefinitions(InputSource inputSource, Resource resource)
后面调用此方法实际对xml文件进行读取和和注册到beanFactory
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
}
}
- doRegisterBeanDefinitions(Element root)
从根元素开始解析,就是beans节点
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
protected void doRegisterBeanDefinitions(Element root) {
preProcessXml(root);
//遍历解析文件内的各种子节点
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
- parseBeanDefinitions遍历解析文件内的各种子节点
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
//通过nameSpace判断是由谁来解析。
if (delegate.isDefaultNamespace(ele)) {
//默认的为xmlns="http://www.springframework.org/schema/beans"
//解析spring默认的4种节点
parseDefaultElement(ele, delegate);
}
else {
//扩展的,比如:aop、dubbo的都走这里进行加载,各自自定义的解析方法META-INF\spring.handlers配置文件中指定了
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
- parseDefaultElement默认的spring的4种节点各自处理
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//import节点直接递归加载一个新的xml文件
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
//alias 别名节点,直接加载到beanFactory
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
//bean节点,BeanDefinition注册到beanFactory中。
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// beans 是一个root节点,递归解析
doRegisterBeanDefinitions(ele);
}
}
以上就是读取bean配置信息的一个完整过程
③ prepareBeanFactory(beanFactory);
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 配置Aware处理器,Aware接口提供给使用方实现,容器通过这个处理器调用
//这些Aware就是下面被ignore的几种,具体调用怎么调用ApplicationContextAwareProcessor里查看
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 将以下接口添加到一个Set集合,默认时只有BeanFactory在这个集合,集合内的接口对应的bean将忽略依赖校验以及自动装配。(ApplicationContextAware是不是很熟悉哈)
//private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 将以下类对应的装配实例,put到一个Map中resolvableDependencies
/** Map from dependency type to corresponding autowired value */
// private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// /** BeanPostProcessors to apply in createBean */
// 添加到private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
/** Cache of singleton objects: bean name --> bean instance */
// private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
//注册环境相关的单例到singletonObjects
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
④ postProcessBeanFactory(beanFactory);
后置处理器,添加servletContextAwareProcessor
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//ServletContextAware,ServletConfigAware处理器
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
//request,response,session等Scope对象注册到
//private final Map<String, Scope> scopes = new LinkedHashMap<String, Scope>(8);
// 同时注册ServletRequest,ServletResponse,HttpSession,WebRequest等的实例到resolvableDependencies
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
//注册"contextParameters", "contextAttributes"等web环境的beanFactory
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
⑤ invokeBeanFactoryPostProcessors(beanFactory);
执行已经注册的后置处理器
⑥ registerBeanPostProcessors(beanFactory);
注册一些后置处理器
⑦ initMessageSource();
MessageSource我也不知道是什么
⑧ initApplicationEventMulticaster();
⑨ onRefresh();
初始化一些特殊的bean实例
⑩ registerListeners();
注册监听器的bean
(11) finishBeanFactoryInitialization(beanFactory);
初始化所有的单例bean实例,除了设置了懒加载的。通过getBean(beanName);
(12) finishRefresh();
protected void finishRefresh() {
// lifecycleProcessor 实例初始化
initLifecycleProcessor();
//
getLifecycleProcessor().onRefresh();
// 发布context刷新事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
三、获取bean实例:getBean
获取bean实例
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//获取beanName
final String beanName = transformedBeanName(name);
Object bean;
// 1. 首先从Map<String, Object> earlySingletonObjects获取缓存的早期的实例
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
//找到bean的话,获取实例。(标记1)这里下面单独讲
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
//2. 如果失败,检查是否已经在当前线程创建实例,是的话异常。(可能是循环引用)
//private final ThreadLocal<Object> prototypesCurrentlyInCreation
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//3. 如果类在当前beanFactory中找不到Definition尝试从父BeanFactory找
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//4. 校验是否已经在Set<String> alreadyCreated有,没有增加
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//5. 下面要开始创建实例了,首先获取RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//6. 获取依赖的bean对应的实例,如果互相引用用,将抛异常。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//Map<String, Set<String>> dependentBeanMap 在被依赖bean的set集合新增当前bean
//这样,就可以知道同一个bean被其他的什么bean依赖了
registerDependentBean(dep, beanName);
//获取被依赖的bean的实例
getBean(dep);
}
}
//7. 如果被创建bean是一个单例,创建当前实例并返回
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//创建实例,这里有调用一些后置程序,下面单独拉出来讲 (标记2)
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
//(标记1)获取实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
//8. 如果是非单例(prototype)创建一个实例
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
//ThreadLocal<Object> prototypesCurrentlyInCreation校验在当前线程是否正在创建实例中
beforePrototypeCreation(beanName);
//创建实例。(标记2)
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//与beforePrototypeCreation相对应,从prototypesCurrentlyInCreation移除
afterPrototypeCreation(beanName);
}
//(标记1)
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
//9. 以上都不是,那么检查是否在request,session等scope中有,没有则创建。(较少用)
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
//标记2
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
//标记1
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
return (T) bean;
}
标记2:createBean(beanName, mbd, args)
这里其实就是根据一个RootBeanDefinition去创建一个bean的实例。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 对于一些特殊的动态的beanDefinition可能需要拷贝一份再使用
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 为需要IOC重写的方法
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
}
try {
//可以从BeanPostProcessors提供一个代理实现类。执行InstantiationAwareBeanPostProcessor。【1】
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
}
// 创建实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
------doCreateBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// 创建bean实例
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// 如果是一个很急切需要的实例,先添加到单例的容器里singletonFactories
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// 填充bean属性,并自动装配bean的属性。
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
}
// Register bean as disposable.
try {
// Map<String, Object> disposableBeans
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
}
return exposedObject;
}
标记1:getObjectForBeanInstance(scopedInstance, name, beanName, mbd)
由createBean后得到了bean的实例。但其实有些实例是工厂类,所以getBean真正需要返回的是工厂类生成的一个真正的实例。这个工厂就是FactoryBean的实现类。
org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
1. 不是FactoryBean的实现类,也不是&开头的beanName之前返回bean实例。
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
2. 如果是工厂bean,通过工厂bean的getObject方法获取实例
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
//获取实例
return factory.getObject();
}
}, acc);
BeanFactory和FactoryBean
BeanFactory :实际就是SpringIOC的容器,存放这bean的定义信息,实例等
FactoryBean:一种特殊的bean,存放于BeanFactory,通过它获取某类实例。
四、总结
通过上面的代码阅读,基本了解IOC器的一个加载过程和bean实例初始化和获取。当然这只是一个主要流程的学习,如果想要理解具体的实现细节,可以再分析一些重要的接口设计等。比如:BeanFactory、ApplicationContext等。
可以参考:http://blog.csdn.net/lisongjia123/article/details/52129340
写得有点粗糙,可能有很多问题,希望理解和指正!