一、IOC容器结构体系
日常工作中常用的spring框架,极大的简化了java程序员的开发,很多时候我们只关心怎么用,但是作为一名专业的程序员,对spring源码的学习还是必不可少的,学习spring源码对我们日常开发的帮助无疑是巨大的,能够提升大家的开发思维模式,好了,接下来让我们来看看Spring IOC容器初始化流程具体是如何实现的。
- 首先介绍一下spring容器的类层次结构图:其中顶层容器接口BeanFactory,我们用到的最多的接口是ApplicationContext,常用实现类有ClassPathXmlApplicationContext、AnnotationConfigApplicationContext、FileSystemXmlApplicationContext、web开发中对应的实现类有AnnotationConfigWebApplicationContext,也就是springmvc容器,至于springmvc容器初始化等过程在本文不再过多的描述了。
二、从最基本的 ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“applicationContext.xml”);作为入口开始分析整个IOC容器初始化过程。
- ClassPathXmlApplicationContext构造函数:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();
}
}
//由构造函数可以锁定初始化IOC容器的核心方法为refresh方法,接下来我们跟进refresh方法。
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
//容器刷新准备工作
this.prepareRefresh();
//创建beanFactory,加载配置文件,创建beanDefinition等
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//为beanFactory设置一些需要设置的参数
this.prepareBeanFactory(beanFactory);
try {
//创建postProcessBeanFactory
this.postProcessBeanFactory(beanFactory);
//调用postProcessBeanFactory,可以实现该接口,在容器beanFactory创建后在
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
refresh方法是由父类AbstractApplicationContext实现,该方法制定了整体的流程结构,某些步骤可以交给子类来具体实现,接下来逐步讲解每个方法中的实现逻辑和思想。
- prepareRefresh()方法:该方法主要进行容器初始化的准备工作。
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (this.logger.isDebugEnabled()) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Refreshing " + this);
} else {
this.logger.debug("Refreshing " + this.getDisplayName());
}
}
//初始化属性资源,用于初始化web应用中的servlet属性等
this.initPropertySources();
//设置ioc容器环境并校验,该方法内部调用了ConfigurablePropertyResolver.validateRequiredProperties()来校验
this.getEnvironment().validateRequiredProperties();
if (this.earlyApplicationListeners == null) {
//设置程序中的监听器,观察者设计模式
this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet();
}
- obtainFreshBeanFactory():创建并刷新BeanFactory工厂,该方法由子类:AbstractRefreshableApplicationContext实现
protected final void refreshBeanFactory() throws BeansException {
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
//默认创建DefaultListableBeanFactory ,该类实现了容器顶层接口BeanFactory
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
//beanFactory设置org.springframework.context.support.ClassPathXmlApplicationContext@77e9807f的地址值
beanFactory.setSerializationId(this.getId());
//该方法中为beanFactory设置是否开启自定义的beanDefinition
this.customizeBeanFactory(beanFactory);
//该方法由子类AbstractXmlApplicationContext实现,负责加载解析xml配置文件并构建出beanDefinition,下面详细介绍该方法
this.loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
1.1.0. loadBeanDefinitions(beanFactory),该方法加载解析配置文件并构建出BeanDefinition:
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//创建beanDefinitionReader,里面调用了父类的super(registry);
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//设置ioc容器资源环境
beanDefinitionReader.setEnvironment(this.getEnvironment());
//设置资源加载类为this(实现了ResourceLoader,可以加载资源)
beanDefinitionReader.setResourceLoader(this);
//设置实体解析器
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//初始化beanDefinitionReader
this.initBeanDefinitionReader(beanDefinitionReader);
//真正的加载beanDefinitionReader,进入该方法解析
this.loadBeanDefinitions(beanDefinitionReader);
}
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
super(registry);
this.errorHandler = new SimpleSaxErrorHandler(this.logger);
this.validationModeDetector = new XmlValidationModeDetector();
this.resourcesCurrentlyBeingLoaded = new NamedThreadLocal("XML bean definition resources currently being loaded");
}
父类的构造函数里设置了默认的资源加载器:this.resourceLoader = new DefaultResourceLoader();并设置了默认的Environment:this.environment = new StandardEnvironment();
1.1.1. this.loadBeanDefinitions(beanDefinitionReader);
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
//得到配置的资源,默认返回null
Resource[] configResources = this.getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//得到applicationContext.xml配置文件
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
//真正加载资源配置文件,调用AbstractBeanDefinitionReader类的loadBeanDefinitions方法解析配置文件并构建beanDefinition
reader.loadBeanDefinitions(configLocations);
}
}
1.1.2. AbstractBeanDefinitionReader.loadBeanDefinitions(configLocations)
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
//该资源加载器之前设置为了org.springframework.context.support.ClassPathXmlApplicationContext@77e9807f
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
} else {
int count;
if (resourceLoader instanceof ResourcePatternResolver) {
try {
//加载applicationContext.xml资源为Resource,getResources的最终实现是在PathMatchingResourcePatternResolver里,该方法主要是记载资源,就不再详细介绍
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
//真正加载资源的方法:,该方法内部调用了XmlBeanDefinitionReader.doLoadBeanDefinitions方法,下面介绍该方法
count = this.loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
} catch (IOException var6) {
throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var6);
}
} else {
Resource resource = resourceLoader.getResource(location);
count = this.loadBeanDefinitions((Resource)resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
}
1.1.3:XmlBeanDefinitionReader.doLoadBeanDefinitions方法
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
//将资源加载为w3c规范的Document结构
Document doc = this.doLoadDocument(inputSource, resource);
//将各个节点封装为beanDefinition,最后真正向IOC容器注册beanDefinition
int count = this.registerBeanDefinitions(doc, resource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
到这里obtainFreshBeanFactory();方法就走完了,接下来看this.prepareBeanFactory(beanFactory);方法;
三、this.prepareBeanFactory(beanFactory):该方法主要对beanFactory做一些设置属性等操作。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
设置beanFactory的classLoader为当前context的classLoader
beanFactory.setBeanClassLoader(this.getClassLoader());
设置beanFactory的表达式语言处理器,spring 3增加了表达式语言的支持
//默认可以使用#{bean.xxx}的形式来调用相关的属性
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性等设置管理一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
// 添加BeanPostProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置了几个忽略自动装配的接口
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);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//增加了对AspectJ的支持
if (beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//添加默认的系统环境bean
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
}
后续流程:this.postProcessBeanFactory(beanFactory)…就不再本节分析了,可以查看后续章节。