spring源码之IOC的非核心部分
Posted lucas2
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring源码之IOC的非核心部分相关的知识,希望对你有一定的参考价值。
前言
这篇是对IOC的非核心部分进行分析,是除去了初始化和依赖注入的部分进行分析。对于非web应用,我们在使用spring时,我们会new一个上下文,比如常用的new ClassPathXmlApplicaionContext("applicationContext.xml")。
那么我们就从这句开始进行分析。
概述
源码分析
- 从new 开始,这里我们可以看到,做了下面几个事情
- 构造方法委托处理,设置父类上下文,这里我们可以看到设置为null,即没有父上下文
- 设置配置文件路径,解析设置的路径放到configLocations中就好
- 判断是否需要刷新上下文,这里refresh=true,所以会刷新上下文
//ClassPathXmlApplicationContext类的方法 public ClassPathXmlApplicationContext(String... configLocations) throws BeansException { this(configLocations, true, null); } //ClassPathXmlApplicationContext类的方法 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } } //AbstractRefreshableConfigApplicationContext类的方法 //设置资源文件路径 public void setConfigLocations(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; } }
- 总入口,刷新上下文
//AbstractApplicationContext类方法 //刷新上下文,模板模式,我们可以通过实现这个抽象类,实现自己的applicationContext public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //为上下文刷新做准备 prepareRefresh(); //获取bean工厂,完成bean定义的注册,这里核心后面分析 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //对上面创建好的bean工厂做预处理 prepareBeanFactory(beanFactory); try { //对bean工厂进行后置处理 postProcessBeanFactory(beanFactory); //调用bean工厂的后置处理器 invokeBeanFactoryPostProcessors(beanFactory); //注册bean的后置处理器 registerBeanPostProcessors(beanFactory); //初始化消息源 initMessageSource(); //初始化事件广播器 initApplicationEventMulticaster(); //初始化一些特殊的bean onRefresh(); //注册监听 registerListeners(); //初始化所有非懒加载的单例 finishBeanFactoryInitialization(beanFactory); //发布合适的事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } //销毁单例bean destroyBeans(); //取消刷新 cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring‘s core, since we // might not ever need metadata for singleton beans anymore... //释放缓存 resetCommonCaches(); } } }
-
为上下文刷新做准备,这里主要做了几件事件
- 设置容器处理激活状态
- 初始和校验属性源,在spring mvc的AbstractRefreshableWebApplicationContext有到
- 初始一个早期事件的空链表
//AbstractApplicationContext类的方法 //为上下文刷新做准备 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>(); }
- 获取bean工厂
核心后面进行分析
- bean工厂的预处理
总结
Aware接口的很简单,但很实用
参考链接
https://www.cnblogs.com/niejunlei/archive/2016/11/11/6054713.html(prepareBeanFactory)
以上是关于spring源码之IOC的非核心部分的主要内容,如果未能解决你的问题,请参考以下文章
Spring5源码分析(006)——IoC篇之核心类DefaultListableBeanFactory和XmlBeanDefinitionReader