Spring IOC源码分析

168 阅读5分钟

调试环境

依赖包

  <properties>
    <spring-version>4.3.16.RELEASE</spring-version>
  </properties>
  <dependencies>
    <!--spring-context 会自动将 spring-core、beans、aop、expression jar包引入-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring-version}</version>
    </dependency>
  </dependencies>

入口代码

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
        User user1a = context.getBean("user1", User.class);
        System.out.println(user1a);
    }
}

配置文件

<bean id="user1" class="org.example.User" primary="true"/>

容器启动主代码

关键类ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {
	super(parent);
        //将配置文件存储到属性configLocations,该属性为String[]类型
	setConfigLocations(configLocations);		
        if (refresh) {
               //关键方法,初始化容器
	       refresh();
	}
}

调用该方法启动容器,也可以重新调用达到刷新容器的效果

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		prepareRefresh();
                //关键代码!!!创建容器,加载配置文件,注册bean
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		prepareBeanFactory(beanFactory);
		try {
			postProcessBeanFactory(beanFactory);
			invokeBeanFactoryPostProcessors(beanFactory);
			registerBeanPostProcessors(beanFactory);
			initMessageSource();
			initApplicationEventMulticaster();
			onRefresh();
			registerListeners();
			finishBeanFactoryInitialization(beanFactory);
			finishRefresh();
		} catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
			       logger.warn("Exception encountered during context 
                                   initialization - " + "cancelling refresh attempt: " + ex);
			}
			destroyBeans();
			cancelRefresh(ex);
			throw ex;
		} finally {
			resetCommonCaches();
		}
	}
}

创建容器

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

加载配置文件,注册bean实例

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	//这两个是抽象方法,在子类AbstractRefreshableApplicationContext实现
        refreshBeanFactory();
	ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 
	if (logger.isDebugEnabled()) {
		logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
	}
	return beanFactory;
}

@Override
protected final void refreshBeanFactory() throws BeansException {
	if (hasBeanFactory()) {//如果已有容器,就关闭容器
		destroyBeans();
		closeBeanFactory();
	}
	try {
		DefaultListableBeanFactory beanFactory = createBeanFactory();//new一个对象
		beanFactory.setSerializationId(getId());
		customizeBeanFactory(beanFactory);//定制化容器的两个属性
                //关键代码
		loadBeanDefinitions(beanFactory);
		synchronized (this.beanFactoryMonitor) {
			this.beanFactory = beanFactory;
		}
	}
	catch (IOException ex) {
		throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
	}
}


如果该ApplicationContext实例的以下属性不为空,则关闭该beanFactory容器

private DefaultListableBeanFactory beanFactory;

定制化是否支持bean定义的覆盖,是否允许循环依赖(实际为设置两个属性的值)

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
	if (this.allowBeanDefinitionOverriding != null) {
		beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
	}
	if (this.allowCircularReferences != null) {
		beanFactory.setAllowCircularReferences(this.allowCircularReferences);
	}
}

关键代码在子类AbstractXmlApplicationContext实现

通过以下代码知,ApplicationContext委托XmlBeanDefinitionReader实例去加载配置文件

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	//创建并初始化实例
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
	beanDefinitionReader.setEnvironment(this.getEnvironment());
	beanDefinitionReader.setResourceLoader(this);
	beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        //忽略
	initBeanDefinitionReader(beanDefinitionReader);
        //关键代码!!!
	loadBeanDefinitions(beanDefinitionReader);
}

跟踪代码loadBeanDefinitions(beanDefinitionReader)最终会执行到以下方法,注意以下的方法是在for循环里面执行的,即每个配置文件就会执行一次

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
	Assert.notNull(encodedResource, "EncodedResource must not be null");
	if (logger.isInfoEnabled()) {
		logger.info("Loading XML bean definitions from " + encodedResource.getResource());
	}
        //ThreadLocal变量储存被加载的xml,防止重复加载
	Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
	if (currentResources == null) {
		currentResources = new HashSet<EncodedResource>(4);
		this.resourcesCurrentlyBeingLoaded.set(currentResources);
	}
	if (!currentResources.add(encodedResource)) {
		throw new BeanDefinitionStoreException(
				"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
	}
	try {
		InputStream inputStream = encodedResource.getResource().getInputStream();
		try {
			InputSource inputSource = new InputSource(inputStream);
			if (encodedResource.getEncoding() != null) {
				inputSource.setEncoding(encodedResource.getEncoding());
			}
                        //关键代码!!!
			return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
		}
		finally {
			inputStream.close();
		}
	} catch (IOException ex) {
		throw new BeanDefinitionStoreException(
				"IOException parsing XML document from " + encodedResource.getResource(), ex);
	} finally {
		currentResources.remove(encodedResource);
		if (currentResources.isEmpty()) {
			this.resourcesCurrentlyBeingLoaded.remove();
		}
	}
}

这里1)将配置文件加载并解析成了Document对象;2)注册bean信息到容器

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
		throws BeanDefinitionStoreException {
	try {
		Document doc = doLoadDocument(inputSource, resource);
                //关键代码!!!
		return registerBeanDefinitions(doc, resource);
	}
	catch (BeanDefinitionStoreException ex) {
		throw ex;
	}
	//...
}

委托给DefaultBeanDefinitionDocumentReader去注册bean信息

@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
	this.readerContext = readerContext;
	logger.debug("Loading bean definitions");
	Element root = doc.getDocumentElement();
	doRegisterBeanDefinitions(root);
}

执行解析

protected void doRegisterBeanDefinitions(Element root) {
	BeanDefinitionParserDelegate parent = this.delegate;
	this.delegate = createDelegate(getReaderContext(), root, parent);

	if (this.delegate.isDefaultNamespace(root)) {
		String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
		if (StringUtils.hasText(profileSpec)) {
			String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
					profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
				if (logger.isInfoEnabled()) {
					logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
							"] not matching: " + getReaderContext().getResource());
				}
				return;
			}
		}
	}
	preProcessXml(root);//空方法,用于子类扩展
        //关键代码!!!
	parseBeanDefinitions(root, this.delegate);
	postProcessXml(root);//空方法,用于子类扩展

	this.delegate = parent;
}

去解析

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;
                                //判断是否为默认标签
				if (delegate.isDefaultNamespace(ele)) {
					parseDefaultElement(ele, delegate);
				}
				else {
					delegate.parseCustomElement(ele);
				}
			}
		}
	}
	else {
		delegate.parseCustomElement(root);
	}
}
//解析默认标签 <beans> <bean> <alias> <import> 四个
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
	if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
		importBeanDefinitionResource(ele);
	}
	else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
		processAliasRegistration(ele);
	}
	else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
		processBeanDefinition(ele, delegate);
	}
	else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
		// recurse
		doRegisterBeanDefinitions(ele);
	}
}

解析标签分为两步

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	//第一步
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
	if (bdHolder != null) {
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
		try {
			//第二步 Register the final decorated instance. 
			BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error("Failed to register bean definition with name '" +
					bdHolder.getBeanName() + "'", ele, ex);
		}
		// Send registration event.
		getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
	}
}

第一步:产生bean信息对象

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
	String id = ele.getAttribute(ID_ATTRIBUTE);
	String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

	List<String> aliases = new ArrayList<String>();
	if (StringUtils.hasLength(nameAttr)) {
		String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
		aliases.addAll(Arrays.asList(nameArr));
	}

	String beanName = id;
	if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
		beanName = aliases.remove(0);
		if (logger.isDebugEnabled()) {
			logger.debug("No XML 'id' specified - using '" + beanName +
					"' as bean name and " + aliases + " as aliases");
		}
	}

	if (containingBean == null) {
		checkNameUniqueness(beanName, aliases, ele);
	}
        //创建BeanDefinition,底层是GenericBeanDefinition实例
	AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
	if (beanDefinition != null) {
		if (!StringUtils.hasText(beanName)) {
			try {
				if (containingBean != null) {
					beanName = BeanDefinitionReaderUtils.generateBeanName(
							beanDefinition, this.readerContext.getRegistry(), true);
				}
				else {
					beanName = this.readerContext.generateBeanName(beanDefinition);
					// Register an alias for the plain bean class name, if still possible,
					// if the generator returned the class name plus a suffix.
					// This is expected for Spring 1.2/2.0 backwards compatibility.
					String beanClassName = beanDefinition.getBeanClassName();
					if (beanClassName != null &&
							beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
							!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
						aliases.add(beanClassName);
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Neither XML 'id' nor 'name' specified - " +
							"using generated bean name [" + beanName + "]");
				}
			}
			catch (Exception ex) {
				error(ex.getMessage(), ele);
				return null;
			}
		}
		String[] aliasesArray = StringUtils.toStringArray(aliases);
		return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
	}

	return null;
}

第二步:把bean信息注册到beanFactory

this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);

数据结构如下:

private final Map<String, BeanDefinition> beanDefinitionMap = 
                                    new ConcurrentHashMap<String, BeanDefinition>(256);
private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);

小结:

容器启动实际进行了以下处理

1.new一个BeanFactory对象

2.加载:根据指定的配置文件,生成Document对象

2.解析:根据Document对象,生成BeanDefinition对象

3.注册:将BeanDefinition对象添加到beanFactory

配置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()));

	//添加一个BeanPostProcessor:ApplicationContextAwareProcessor
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        
        //如果某个对象依赖下面的几个接口实现类,在自动装配的时候忽略它们,spring会通过其它方式来
        //处理这些依赖
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
	beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

	//把指定的几个对象新建好,如果某个对象依赖以下几个,会注入这里存储好的对象
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	//再添加一个BeanPostProcessor:ApplicationListenerDetector
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	//忽略
	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()));
	}

	// Register default environment beans.
        // 新建几个单例对象
	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());
	}
}

1.beanFactory.addBeanPostProcessor

@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
	Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
	this.beanPostProcessors.remove(beanPostProcessor);
	this.beanPostProcessors.add(beanPostProcessor);
	if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
		this.hasInstantiationAwareBeanPostProcessors = true;
	}
	if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
		this.hasDestructionAwareBeanPostProcessors = true;
	}
}

数据结构

	private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();

2.beanFactory.ignoreDependencyInterface

public void ignoreDependencyInterface(Class<?> ifc) {
	this.ignoredDependencyInterfaces.add(ifc);
}

数据结构

private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();

3.beanFactory.registerResolvableDependency

@Override
public void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) {
	Assert.notNull(dependencyType, "Dependency type must not be null");
	if (autowiredValue != null) {
		if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
			throw new IllegalArgumentException("Value [" + autowiredValue +
					"] does not implement specified dependency type [" + dependencyType.getName() + "]");
		}
		this.resolvableDependencies.put(dependencyType, autowiredValue);
	}
}

数据结构

private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16);

4.beanFactory.registerSingleton

@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
	super.registerSingleton(beanName, singletonObject);

	if (hasBeanCreationStarted()) {
		// Cannot modify startup-time collection elements anymore (for stable iteration)
		synchronized (this.beanDefinitionMap) {
			if (!this.beanDefinitionMap.containsKey(beanName)) {
				Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames.size() + 1);
				updatedSingletons.addAll(this.manualSingletonNames);
				updatedSingletons.add(beanName);
				this.manualSingletonNames = updatedSingletons;
			}
		}
	}
	else {
		// Still in startup registration phase
		if (!this.beanDefinitionMap.containsKey(beanName)) {
			this.manualSingletonNames.add(beanName);
		}
	}

	clearByTypeCache();
}

//最终调用
protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}

数据结构

/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = 
                                                new ConcurrentHashMap<String, Object>(256);

/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = 
                                                 new HashMap<String, ObjectFactory<?>>(16);

/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = 
                                                 new HashMap<String, Object>(16);

/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);

注册PostProcessBeanFactory

通过上述分析,到此之前,Bean都加载、解析、注册完成了,但是还没有初始化,该步骤可以添加一些特殊的PostProcessBeanFactory实现类去做些拓展功能

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //与上述类似,新增一个BeanPostProcessor:ServletContextAwareProcessor
	beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
	//与上述类似,自动装配时候忽略以下接口
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
	beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
        
	WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
	//注册一些单例bean
        WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

处理PostProcessBeanFactory

注册BeanPostProcessor

初始化国际化

初始化广播器

注册事件监听器

初始化非懒加载的对象

广播事件