栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring IOC源码分析1

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring IOC源码分析1

Spring容器使用
public static void main( String[] args ) {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
    Person bean = applicationContext.getBean(Person.class);
    System.out.println(bean);
}

Spring Ioc初始化一共分为三个步骤:定位,加载,注册。定位就是找到Bean的配置信息,加载就是读取Bean的配置信息,注册就是将Bean的配置信息注册到IOC容器。
本篇是IOC初始化的第一步,定位。

IOC 定位的执行流程

IOC定位代码分析

通过构造器启动Spring容器

//构造器,传入一个配置文件的路径,支持多个配置文件,走重载的构造方法
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
	this(new String[] {configLocation}, true, null);
}
//实际上是调用了这个构造器
public ClassPathXmlApplicationContext(
		String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
		throws BeansException {

	super(parent);//调用父类构造器,生成资源加载器
	setConfigLocations(configLocations);//设置配置文件
	if (refresh) {
		refresh();//启动Spring容器
	}
}
先看一下ClassPathXmlApplicationContext构造器的第一步做了什么
//ClassPathXmlApplicationContext 的父构造器
public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}
//AbstractXmlApplicationContext 的父构造器
public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}
//AbstractRefreshableConfigApplicationContext 的父构造器
public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}
//AbstractRefreshableApplicationContext 的父构造器   这里做了两件事
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
	this();//设置一个资源加载器,以后可以加载资源
	setParent(parent);
}
//先看AbstractApplicationContext 构造器中的第一步
//这里会获取一个资源加载器
public AbstractApplicationContext() {
	this.resourcePatternResolver = getResourcePatternResolver();
}
//获取资源加载器
protected ResourcePatternResolver getResourcePatternResolver() {
	//AbstractApplicationContext的继承关系
	//public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext
	//AbstractApplicationContext继承DefaultResourceLoader,因此也是一个资源加载器
	return new PathMatchingResourcePatternResolver(this);
}
//PathMatchingResourcePatternResolver 的构造器,将AbstractApplicationContext资源加载器设置给自己的成员变量
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
	Assert.notNull(resourceLoader, "ResourceLoader must not be null");
	//设置Spring的资源加载器
	this.resourceLoader = resourceLoader;
}
//再看AbstractApplicationContext 构造器中的第二步
//上面ClassPathXmlApplicationContext 调用的时候,传进来的是null,就什么都没做
@Override
public void setParent(@Nullable ApplicationContext parent) {
	this.parent = parent;
	if (parent != null) {
		Environment parentEnvironment = parent.getEnvironment();
		if (parentEnvironment instanceof ConfigurableEnvironment) {
			getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
		}
	}
}

结合来看,ClassPathXmlApplicationContext 构造器的第一步就是生成了一个资源加载器

再看一下ClassPathXmlApplicationContext构造器的第二步做了什么
//调用了父类 AbstractRefreshableConfigApplicationContext 的方法
//传入配置文件路径,可能为多个
public void setConfigLocations(@Nullable String... locations) {
	if (locations != null) {
		Assert.noNullElements(locations, "Config locations must not be null");
		this.configLocations = new String[locations.length];
		for (int i = 0; i < locations.length; i++) {
			// 解析配置文件路径并复制给成员变量
			this.configLocations[i] = resolvePath(locations[i]).trim();
		}
	}
	else {
		this.configLocations = null;
	}
}
//解析配置文件路径
protected String resolvePath(String path) {
	return getEnvironment().resolveRequiredPlaceholders(path);
}
//调用了父类 AbstractApplicationContext 的方法,获取环境
//上面可以看到,如果第一步传入的参数不为null,也会调用这个方法
@Override
public ConfigurableEnvironment getEnvironment() {
	if (this.environment == null) {
		this.environment = createEnvironment();
	}
	return this.environment;
}
//AbstractApplicationContext 的方法,生成一个标准的环境
protected ConfigurableEnvironment createEnvironment() {
	return new StandardEnvironment();
}
//解析
@Override
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
	return this.propertyResolver.resolveRequiredPlaceholders(text);
}
// propertyResolver 的由来
protected final Log logger = LogFactory.getLog(getClass());
private final MutablePropertySources propertySources = new MutablePropertySources(this.logger);
private final ConfigurablePropertyResolver propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);
//解析必要的占位符
@Override
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
	if (this.strictHelper == null) {
		this.strictHelper = createPlaceholderHelper(false);
	}
	return doResolvePlaceholders(text, this.strictHelper);
}
//创建占位符处理器
private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
	return new PropertyPlaceholderHelper(this.placeholderPrefix, this.placeholderSuffix,
			this.valueSeparator, ignoreUnresolvablePlaceholders);
}
//入参分别是占位符前缀(${),占位符后缀(}),值分隔符(:),是否忽略解析占位符
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
		@Nullable String valueSeparator, boolean ignoreUnresolvablePlaceholders) {

	Assert.notNull(placeholderPrefix, "'placeholderPrefix' must not be null");
	Assert.notNull(placeholderSuffix, "'placeholderSuffix' must not be null");
	this.placeholderPrefix = placeholderPrefix;
	this.placeholderSuffix = placeholderSuffix;
	String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix);
	if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) {
		this.simplePrefix = simplePrefixForSuffix;
	}
	else {
		this.simplePrefix = this.placeholderPrefix;
	}
	this.valueSeparator = valueSeparator;
	this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
}
//wellKnownSimplePrefixes 的初始化 是个静态块
static {
	wellKnownSimplePrefixes.put("}", "{");
	wellKnownSimplePrefixes.put("]", "[");
	wellKnownSimplePrefixes.put(")", "(");
}
//解析占位符,返回资源地址
private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
	return helper.replacePlaceholders(text, this::getPropertyAsRawString);
}
//下面不再跟了

可以看出来,这一步主要是解析资源文件位置,并生成占位符解析器

再看一下ClassPathXmlApplicationContext构造器的第三步做了什么
public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {//加锁
			//调用容器准备刷新的方法,获取容器的当时时间,设置启动标志,验证必要的属性,生成空的事件集合
			prepareRefresh();

			//ioc的初始化在这里
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			prepareBeanFactory(beanFactory);

			try {
				postProcessBeanFactory(beanFactory);

				//BeanFactory后置处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				//bean后置处理器
				registerBeanPostProcessors(beanFactory);

				//初始化信息源
				initMessageSource();

				//初始化容器事件传播器.
				initApplicationEventMulticaster();

				//调用子类的某些特殊Bean初始化方法
				onRefresh();

				//注册事件监听器.
				registerListeners();

				//初始化非lazy的bean
				finishBeanFactoryInitialization(beanFactory);

				//发布容器事件,结束refresh
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				//销毁已创建的Bean
				destroyBeans();

				//取消refresh操作
				cancelRefresh(ex);

				throw ex;
			}

			finally {
				resetCommonCaches();
			}
		}
	}

spring容器在第三步,refresh方法中初始化,具体是在 obtainFreshBeanFactory 方法中

下面看obtainFreshBeanFactory 方法
	//获得新的BeanFactory
	//AbstractApplicationContext#obtainFreshBeanFactory
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//刷新BeanFactory
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
	//刷新BeanFactory在AbstractRefreshableApplicationContext#refreshBeanFactory方法中实现
	protected final void refreshBeanFactory() throws BeansException {
		//如果已经有容器,销毁容器中的bean,关闭容器
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//创建IOC容器
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			//对IOC容器进行定制化
			customizeBeanFactory(beanFactory);
			//加载BeanDefinition ioc初始化第二步
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
//创建IOC容器
	protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}
	//AbstractApplicationContext#getInternalParentBeanFactory 这里会返回null
	protected BeanFactory getInternalParentBeanFactory() {
		return (getParent() instanceof ConfigurableApplicationContext) ?
				((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
	}
	//private ApplicationContext parent;  在上面构造器的第一步传入的parent是 null
	public ApplicationContext getParent() {
		return this.parent;
	}
	//看看 DefaultListableBeanFactory 构造器做了啥
	public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		super(parentBeanFactory);
	}
	public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		this();
		setParentBeanFactory(parentBeanFactory);
	}
	public AbstractAutowireCapableBeanFactory() {
		super();
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
	}
	public AbstractBeanFactory() {
	}
	public void setParentBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
			throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
		}
		this.parentBeanFactory = parentBeanFactory;
	}
	//这一步构造了ioc容器,AbstractBeanFactory
	
	//定制化ioc容器
	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		//是否允许beanDefinition重写
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		//是否允许循环依赖
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

这个过程是ioc初始化的第一步,初始化资源,Beanfactory,获取Bean定位

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/446252.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号