详解Spring ApplicationContext加载过程

网友投稿 903 2023-02-04

详解Spring ApplicationContext加载过程

详解Spring ApplicationContext加载过程

1、找准入口,使用ClassPathXmlApplicationContext的构造方法加载配置文件,用于加载classPath下的配置文件

//第一行,执行完成之后就完成了spring配置文件的加载,刷新spring上下文

ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(

"classpath:spring-mvc.xml");

//获取实例Bean

Person person=context.getBean("person",Person.class);

2、ClassPathXmlApplicationContext构造方法源码如下:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)

throws BeansException {

//设置父级的ApplicationContext,null

super(parent);

//1.设置配置文件的路径, 2. 将路径中的占位符${placeholder}使用系统的变量替换

setConfigLocations(configLocations);

if (refresh) {

refresh();

}

}

3、主要方法为setConfigLocation(configLocation),这个方法调用其父类AbstractRefreshableConfigApplicationContext中的方法

//locations : 配置文件路径

public void setConfigLocations(String[] locations) {

if (locations != null) {

//断言

Assert.noNullElements(locations, "Config locations must not be null");

//存储配置文件路径的数组,存储去掉占位符后的文件路径数组

this.configLocations = new String[locations.length];

//遍历locations,解析占位符

for (int i = 0; i < locations.length; i++) {

//调用resolvePath解析占位符

this.configLocations[i] = resolvePath(locations[i]).trim();

}

}

else {

this.configLocations = null;

}

}

4、进入resovePath的源码,实际上执行的是AbstractPropertyResolver的doResolverPlaceholders方法

/**

* text : 需要解析的路径

* PropertyPlaceholderHelper : 这个是解析系统占位符的辅助类,主要用来将占位符替换成系统的环境变量

*/

private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {

//调用PropertyPlaceholderHelper类中的replacePlaceholders方法

return helper.replacePlaceholders(text, new PropertyPlaceholderHelper.PlaceholderResolver() {

public String resolvePlaceholder(String placeholderName) {

return getPropertyAsRawString(placeholderName);

}

});

}

5、进入PropertyHelper的replacePlaceholder方法,实际上调用PropertyPlaceholderHelper的parseStringValue解析占位符

public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {

Assert.notNull(value, "Argument 'value' must not be null.");

//调用的是parseStringValue方法

return parseStringValue(value, placeholderResolver, new HashSet());

}

/**

* strVal : 需要解析的字符串,就是配置文件的路径

* placeholderResolver : 策略接口,占位符解析器

* visitedPlaceholders : 存储已经访问过的占位符

**/

protected String parseStringValue(

String strVal, PlaceholderResolver placeholderResolver, Set visitedPlaceholders) {

//将strval转换成StringBuilder,便于后续到操作

StringBuilder buf = new StringBuilder(strVal);

//this.placeholderPrefix这个是占位符的前缀 ${,在创建PropertyHelper的时候就已经指定了占位符的placeholderPrefix="${" ,placeholderSuffix="}",valueSeparator=":"

//获取前缀在这个配置文件路径中的开始索引

int startIndex = strVal.indexOf(this.placeholderPrefix);

while (startIndex != -1) {

//占位符前缀在路径中的结束索引

int endIndex = findhttp://PlaceholderEndIndex(buf, startIndex);

//如果结束索引存在

if (endIndex != -1) {

//此时取出${plcaeholder}中的占位符内容placeholder

String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);

//保存取出来的占位符内容platTxMVFXHpsceholder

String originalPlaceholder = placeholder;

//如果占位符中的内容已经被访问过了,抛出出异常返回,递归结束的条件

if (!visitedPlaceholders.add(originalPlaceholder)) {

throw new IllegalArgumentException(

"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");

}

//递归解析已经取出的占位符中的内容 palceholder

placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);

//这个最重要的一步,将解析占位符内容placeholder的值,比如将java.version转换成1.8.0_60

String propVal = placeholderResolver.resolvePlaceholder(placeholder);

if (propVal == null && this.valueSeparator != null) {

int separatorIndex = placeholder.indexOf(this.valueSeparator);

if (separatorIndex != -1) {

String actualPlaceholder = placeholder.substring(0, separatorIndex);

String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());

propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);

if (propVal == null) {

propVal = defaultValue;

}

}

}

//如果解析出来的占位符不为空,比如${java.version}将被解析成 1.8.0_60

if (propVal != null) {

//此时继续递归解析出1.8.0_60中的占位符

propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);

//将路径中的占位符替换成系统变量的值,比如将${java.version} 替换成 1.8.0_60

buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);

if (logger.isTraceEnabled()) {

logger.trace("Resolved placeholder '" + placeholder + "'");

}

//继续在路径字符串中剩余的子串中查找占位符,如果有占位符,那么还会继续解析占位符

startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());

}

else if (this.ignoreUnresolvablePlaceholders) {

// Proceed with unprocessed value.

startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());

}

else {

throw new IllegalArgumentException("Could not resolve placeholder '" +

placeholder + "'" + " in string value \"" + strVal + "\"");

}

//将已转换成功的占位符从以访问的集合中移除即可

visitedPlaceholders.remove(originalPlaceholder);

}

else {

startIndex = -1;

}

}

return buf.toString(); //将解析完成之后的配置文件返回

}

6、然后是ClassPathXmlApplicationContext中的refresh方法,实际上调用的是父类AbstractApplicationContext的方法

//刷新spring上下文

public void refresh() throws BeansException, IllegalStateException {

synchronized (this.startupShutdownMonitor) {

//在刷新之前设置一些参数,比如设置开始时间戳,上下文是否激活的标志,输出刷新上下文的信息,验证一些必要的属性

prepareRefresh();

//需要创建beanFactory,如果已经存在beanFactory,那么关闭,详细其请看 10

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 准备上下文工厂,详情见12

prepareBeanFactory(beanFactory);

try {

//允许子类向后置处理器添加组件

postProcessBeanFactory(beanFactory);

// 调用BeanFactoryPostProcessor和BeanDefintionRegistoryPostProcessor这两个后置处理器

invokeBeanFactoryPostProcessors(beanFactory);

// 注册BeanPostProcessor,用来拦截bean的创建,详情见 14

registerBeanPostProcessors(beanFactory);

//初始化消息源

initMessageSource();

// 初始化应用程序事件广播器,用户可以自定义一个事件广播器,如果用户没有定义,那么使用默认的事件广播器SimpleApplicationEventMulticaster

initApplicationEventMulticaster();

// 在其他子类中初始化bean

onRefresh();

// 检测事件-

registerListeners();

//完成实例化剩余的单例(non-lazy-init)

finishBeanFactoryInitialization(beanFactory);

// 完成刷新,初始化生命周期处理器......

finishRefresh();

}

catch (BeansException ex) {

// Destroy already created singletons to avoid dangling resources.

destroyBeans();

// Reset 'active' flag.

cancelRefresh(ex);

// Propagate exception to caller.

throw ex;

}

}

}

7、进入obtainFreshBeanFactory方法

//AbastractApplicationContext的方法

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {

//实际刷新上下文的方法,这个方法就是实际的刷新上下文方法,其中会调用loadBeanDefinitions(beanFactory);加载配置文件中的内容到BeanDefiniton中

refreshBeanFactory();

ConfigurableListableBeanFactory beanFactory = getBeanFactory();

if (logger.isDebugEnabled()) {

logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);

}

return beanFactory;

}

//org.springframework.context.support.AbstractRefreshableApplicationContext中的方法

//AbstractApplicationContext的子类中的方法

@Override

protected final void refreshBeanFactory() throws BeansException {

//如果其中有beanfactory,那么销毁

if (hasBeanFactory()) {

destroyBeans();

closeBeanFactory();

}

try {

//重新创建一个beanFactory

DefaultListableBeanFactory beanFactory = createBeanFactory();

//设置序列化id

beanFactory.setSerializationId(getId());

//定制beanFactory,设置相关属性,包括是否允许覆盖名称的不同定义的对象及循环依赖以及

//设置@Autowired和@Qualifier,注解解析器QualifierAnnotationAutowireCandidateResolver

customizeBeanFactory(beanFactory);

//加载BeanDefine 详情见 11

loadBeanDefinitions(beanFactory);

synchronized (this.beanFactoryMonitor) {

this.beanFactory = beanFactory;

}

}

catch (IOException ex) {

throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);

}

}

8、进入loadBeanDefinitions(beanFactory)方法

//这个是org.springframework.context.support.AbstractXmlApplicationContext类中的方法

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {

//创建要给beanDefinitionReader,用于读取BeanDefinition

XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

//配置XmlBeanDefinitionReader

beanDefinitionReader.setEnvironment(this.getEnvironment());

beanDefinitionReader.setResourceLoader(this);

beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

initBeanDefinitionReader(beanDefinitionReader);

//加载BeanDefiniton,主要的功能从配置文件中读取BeanDefiniton注册到注册表中

loadBeanDefinitions(beanDefinitionReader);

}

9、prepareBeanFactory:准备BeanFactory

//准备BeanFactory,设置一些参数,比如后置处理器,

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

//设置类加载器

beanFactory.setBeanClassLoader(getClassLoader());

//设置表达式解析器,用来解析BeanDefiniton中的带有表达式的值

beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// 配置后置处理器,主要的作用就是在spring实例化bean的前后做一些操作

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

//忽略自动装配的类,这些类都不能使用@Resource或者@Autowired自动装配获取对象

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));

//检查这些类是否被

if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {

beanFactory.addBeanPostProcessor(new LoadTimeWeavehttp://rAwareProcessor(beanFactory));

beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));

}

// 将下面这些类注册到容器中,使用registerSingleton方法注册,我们可以直接从容器中获取这些类的对象使用

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

}

}

10、调用BeanFactory的后置处理器,主要的功能就是调用注册在容器中的BeanFactoryPostProcessor和BeanDefinitionRegistoryPostProcessor

//实例化和调用BeanFactory后置处理器,必须在单例实例化之前调用

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {

//调用后置处理器注册委托类的方法调用,getBeanFactoryPostProcessors用于获取注册的全部的BeanFactoryPostProcessor

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

}

//实际的调用方法,PostProcessorRegistrationDelegate中的方法

public static void invokeBeanFactoryPostProcessors(

ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

// Invoke BeanDefinitionRegistryPostProcessors first, if any.

Set processedBeans = new HashSet();

//如果beanFactory是BeanDefinitionRegistry的子类,BeanDefinitionRegistry使用来向注册表中注册Bean的元信息的(BeanDefintion)

if (beanFactory instanceof BeanDefinitionRegistry) {

BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

//存放BeanFactoryPostProcessor

List regularPostProcessors = new LinkedList();

//存放BeanDefinitionRegistryPostProcessor

List registryPostProcessors =

new LinkedList();

//遍历。判断是否是BeanDefinitionRegistryPostProcessor实例

for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {

if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {

BeanDefinitionRegistryPostProcessor registryPostProcessor =

(BeanDefinitionRegistryPostProcessor) postProcessor;

//调用BeanDefinitionRegistryPostProcessor

registryPostProcessor.postProcessBeanDefinitionRegistry(registry);

//添加

registryPostProcessors.add(registryPostProcessor);

}

else {

//表示这个是BeanFactoryPostProcessor实例,添加进集合

regularPostProcessors.add(postProcessor);

}

}

//--- 根据类型类型获取beanFactory中注册的BeanDefinitionRegistryPostProcessor的bean的所有名称数组

String[] postProcessorNames =

beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

// ---- 首先调用的是BeanDefinitionRegistryPostProcessor类型的后置处理器

//存放实现PriorityOrdered这个接口的BeanDefinitionRegistryPostProcessor

List priorityOrderedPostProcessors = new ArrayList();

//遍历,如果实现了PriorityOrdered这个接口就保存下来

for (String ppName : postProcessorNames) {

if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

processedBeans.add(ppName);

}

}

//按照优先级排序

OrderComparator.sort(priorityOrderedPostProcessors);

//添加进入集合

registryPostProcessors.addAll(priorityOrderedPostProcessors);

//首先调用实现PriorityOrdered这个接口的BeanDefinitionRtTxMVFXHpsegistryPostProcessor

invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

// ---- 下面是调用实现Orderd这个接口的BeanDefinitionRegistryPostProcessor

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

List orderedPostProcessors = new ArrayList();

for (String ppName : postProcessorNames) {

if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {

orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

processedBeans.add(ppName);

}

}

OrderComparator.sort(orderedPostProcessors);

registryPostProcessors.addAll(orderedPostProcessors);

invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

// ---- 最终调用剩余全部的BeanDefinitionRegistryPostProcessor

boolean reiterate = true;

while (reiterate) {

reiterate = false;

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

for (String ppName : postProcessorNames) {

if (!processedBeans.contains(ppName)) {

BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);

registryPostProcessors.add(pp);

processedBeans.add(ppName);

pp.postProcessBeanDefinitionRegistry(registry);

reiterate = true;

}

}

}

// 调用BeanFactoryPostProcessor接口中的方法,因为BeanDefitionRegistory继承了这个接口

invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);

invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

}

else {

// Invoke factory processors registered with the context instance.

invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);

}

//--- 下面是调用实现BeanFactoryPostProcessor接口的类,和上面的流程一样

String[] postProcessorNames =

beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,

// Ordered, and the rest.

List priorityOrderedPostProcessors = new ArrayList();

List orderedPostProcessorNames = new ArrayList();

List nonOrderedPostProcessorNames = new ArrayList();

for (String ppName : postProcessorNames) {

if (processedBeans.contains(ppName)) {

// skip - already processed in first phase above

}

else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));

}

else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {

orderedPostProcessorNames.add(ppName);

}

else {

nonOrderedPostProcessorNames.add(ppName);

}

}

// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.

OrderComparator.sort(priorityOrderedPostProcessors);

invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.

List orderedPostProcessors = new ArrayList();

for (String postProcessorName : orderedPostProcessorNames) {

orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));

}

OrderComparator.sort(orderedPostProcessors);

invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.

List nonOrderedPostProcessors = new ArrayList();

for (String postProcessorName : nonOrderedPostProcessorNames) {

nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));

}

invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

}

11、注册BeanPostProcessor,用来拦截Bean的创建,这个接口可以实现在Bean初始化和初始化之后执行相关的操作

//依然这里依然调用的PostProcessorRegistrationDelegate,其中包含了注册后置处理器和调用后置处理器的方法,相当于一个代理人

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {

PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);

}

//PostProcessorRegistrationDelegate中的注册BeanPostProcessors的方法

//其中beanFactory这个新创建的beanFactory,其中的BeanPostProcessor都没有注册,applicationContext这个是之前创建的,其中的处理器已经注册过了

public static void registerBeanPostProcessors(

ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

//根据类型新加载全部的BeanFactoryProcessor的类,

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

//创建BeanPostProcessor检测器

int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;

beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

// Separate between BeanPostProcessors that implement PriorityOrdered,

// Ordered, and the rest.

List priorityOrderedPostProcessors = new ArrayList();

List internalPostProcessors = new ArrayList();

List orderedPostProcessorNames = new ArrayList();

List nonOrderedPostProcessorNames = new ArrayList();

for (String ppName : postProcessorNames) {

if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);

priorityOrderedPostProcessors.add(pp);

if (pp instanceof MergedBeanDefinitionPostProcessor) {

internalPostProcessors.add(pp);

}

}

else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {

orderedPostProcessorNames.add(ppName);

}

else {

nonOrderedPostProcessorNames.add(ppName);

}

}

// First, register the BeanPostProcessors that implement PriorityOrdered.

OrderComparator.sort(priorityOrderedPostProcessors);

registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

// Next, register the BeanPostProcessors that implement Ordered.

List orderedPostProcessors = new ArrayList();

for (String ppName : orderedPostProcessorNames) {

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);

orderedPostProcessors.add(pp);

if (pp instanceof MergedBeanDefinitionPostProcessor) {

internalPostProcessors.add(pp);

}

}

OrderComparator.sort(orderedPostProcessors);

registerBeanPostProcessors(beanFactory, orderedPostProcessors);

// Now, register all regular BeanPostProcessors.

List nonOrderedPostProcessors = new ArrayList();

for (String ppName : nonOrderedPostProcessorNames) {

BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);

nonOrderedPostProcessors.add(pp);

if (pp instanceof MergedBeanDefinitionPostProcessor) {

internalPostProcessors.add(pp);

}

}

registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

// Finally, re-register all internal BeanPostProcessors.

OrderComparator.sort(internalPostProcessors);

registerBeanPostProcessors(beanFactory, internalPostProcessors);

beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

}

以上就是详解Spring ApplicationContext加载过程的详细内容,更多关于Spring ApplicationContext加载过程的资料请关注我们其它相关文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring事务的开启原理详解
下一篇:mybatis中insert主键ID获取和多参数传递的示例代码
相关文章

 发表评论

暂时没有评论,来抢沙发吧~