Spring框架核心流程
文章目录
- 一、Spring的使用
- 二、核心流程
- 2.1通过XML加载的方式启动
- 总流程:
- 2.1.1 创建ApplicationContext对象
- 2.1.1.1 构建父类
- 2.1.1.2 调用setConfiguration()
- 2.1.1.3** 执行refresh() (核心)
- refresh()-----prepareRefresh()
- refresh()-----obtainFreshBeanFacotry()(重点)
- refresh()-----prepareBeanFactory(beanFacory)
- refresh()-----postProcessBeanFactory(beanFactory)
- refresh()-----invokeBeanFactoryPostProcessors(beanFactory)(重点)
- refresh()-----registerBeanPostProcessors(beanFactory)
- refresh()-----initMessageSource()
- refresh()-----initApplicationEventMulticaster()
- refresh()-----onRefresh()(重点)
- refresh()-----registerListeners()
- refresh()-----finishBeanFactoryInitialization(beanFactory)(重点)
- refresh()-----finishRefresh()
- 2.1.2 使用
- 2.2通过注解加载的方式启动
一、Spring的使用
Spring启动的方式有很多种,大体分为XML方式和注解方式。
XML方式使用ClassPathXmlApplicationContext或者FileSystemXmlApplicationContext
- FileSystemXmlApplicationContext是从文件系统加载Bean和相关资源
- ClassPathXmlApplicationContext则是从classPath下的配置文件获取Bean的信息以及相关资源。
注解方式则需要配合@ComponentScan注解和配置类来使用,适用于无配置文件,通过注解进行配置的Spring启动。
二、核心流程
2.1通过XML加载的方式启动
使用方式:
//创建springIOC容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
//从容器中获取mapper
DepartmentMapper bean = ioc.getBean(DepartmentMapper.class);
总流程:
-
创建父类
ClassPathXmlApplicationContext —> AbstractXmlApplicationContext
—>AbstractRefreshableConfigApplicationContext
—>AbstractRefreshableApplicationContext
—>AbstractApplicationContext
创建完设置一些属性 -
调用setConfigurations方法
2.1 调用resolvePath方法,该方法创建Environment对象并调用Environment的resolveRequiredPlaceholders解析配置文件中的占位符。
2.2 在创建Environment的过程中,Environment通过customizePropertySources加载系统变量和环境变量。
-
refresh()-----prepareRefresh
设置了一个ApplicationEvent容器(存放早期事件),同时设置关闭标志为false,开启标志为true。
-
refresh()-----obtainFreshBeanFacotry()(重点)
创建BeanFactory,加载并解析XML文件,通过XmlBeanDefinitionReader将XML中配置的要加载的Bean,封装为BeanDefinition放入BeanFactory。
-
refresh()-----prepareBeanFactory(beanFacory)
为BeanFactory设置一些属性,此时BeanFactory只含有我们在配置文件配置的那些Bean的BeanDefinition定义,再为其设置表示Environment的Bean及其他的Bean还有一些PostProcessor等
-
refresh()-----postProcessBeanFactory(beanFactory)
空方法,留给子类扩展。用于定制BeanFactory
-
refresh()-----invokeBeanFactoryPostProcessors(beanFactory)(重点)
执行所有注册的BeanFactoryPostProcessor,特别是ConfigurationClassPostProcessor,该类负责处理我们设置的配置类,即处理含有@Component、@Import、@Bean注解的类,将该类含有的这些注解进行处理。例如扫描@Component注解指向的包,将该包下的@component注解标注类加入到BeanFactory。
在执行的时候,先执行所有实现PriorityOrder接口的BeanFactoryPostProcessor的postProcessBeanDefinitionRegistry(),再执行所有实现Order接口的,最后是其余的普通的,执行这些BeanFactoryPostProcessor的postProcessBeanDefinitionRegistry()以后,再执行他们的PostProcessorBeanFactory()方法。 -
refresh()-----registerBeanPostProcessors(beanFactory)
将BeanFactory中的BeanPostProcessor按照PriorityOrder、Order、普通的、容器内的这四个级别排序。 -
refresh()-----initMessageSource()
进行一些国际化的设置
-
refresh()-----initApplicationEventMulticaster()
初始化事件多播器 -
refresh()-----onRefresh()(重点)
空方法,留给子类实现,SpringBoot通过该方法完成Spring容器启动的同时启动Tomcat容器。
-
refresh()-----registerListeners()
将事件监听器注册到事件多播器上,当发生Spring发生某个事件时,会获取多播器,从多播器中找到监听该事件的监听器,然后通知这些监听者。 -
refresh()-----finishBeanFactoryInitialization(beanFactory)(重点)
完成非懒加载的类的实例化(解决循环依赖问题) -
refresh()-----finishRefresh()
创建声明周期对象,并启动。
2.1.1 创建ApplicationContext对象
//configLocation为配置文件的位置
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[]{configLocation}, true, (ApplicationContext)null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();
}
}
2.1.1.1 构建父类
这里首先调用了父类的构造方法,ClassPathXmlApplicationContext的父类是AbstractXmlApplicationContext。这一步主要设置了一些属性
public AbstractXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
----------又调用了父类的构造方法
public AbstractRefreshableConfigApplicationContext(ApplicationContext parent) {
super(parent);
}
-------继续深入
public AbstractRefreshableApplicationContext(ApplicationContext parent) {
super(parent);
}
public AbstractApplicationContext(ApplicationContext parent) {
this();
this.setParent(parent);
}
//传递过来的Parent为null,调用this();
public AbstractApplicationContext() {
this.logger = LogFactory.getLog(this.getClass());
this.id = ObjectUtils.identityToString(this);
this.displayName = ObjectUtils.identityToString(this);
this.beanFactoryPostProcessors = new ArrayList();
this.active = new AtomicBoolean();
this.closed = new AtomicBoolean();
this.startupShutdownMonitor = new Object();
this.applicationListeners = new LinkedHashSet();
this.resourcePatternResolver = this.getResourcePatternResolver();
}
//设置了一些属性,初始化了BeanFactoryPostProcessor容器和监听器容器
2.1.1.2 调用setConfiguration()
然后调用了ClassPathXmlApplicationContext的setConfiguration方法。这一步主要加载了系统的资源以及环境变量等,还有一个作用就是解析配置文件中的占位符
this.setConfigLocations(configLocations);
------------该方法的具体代码
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) {
//创建一个Environment对象,同时加载资源
this.configLocations[i] = this.resolvePath(locations[i]).trim();
}
} else {
this.configLocations = null;
}
}
---------------resolvePath方法
protected String resolvePath(String path) {
return this.getEnvironment().resolveRequiredPlaceholders(path);
}
//首先判断当前的environment对象是否为空,是空的话则创建一个StandarEnvironment对象,
//创建该对象会加载系统资源。
//AbtsractEnvironment为StandarEnvironment类的抽象类
public AbstractEnvironment() {
this.propertySources = new MutablePropertySources(this.logger);
this.propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);
//这句很关键,加载了系统资源
this.customizePropertySources(this.propertySources);
-------------分别加载了系统的属性和系统的环境变量
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new MapPropertySource("systemProperties", this.getSystemProperties()));
propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", this.getSystemEnvironment()));
}
---------------创建完Environment,调用Environment中PropertyResolver
---------------的resolveRequiredPlaceholders(path)方法
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
return this.propertyResolver.resolveRequiredPlaceholders(text);
}
--------------调用propertyResolver.resolveRequiredPlaceholders(text)
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
if (this.strictHelper == null) {
this.strictHelper = this.createPlaceholderHelper(false);
}
//解析占位符
return this.doResolvePlaceholders(text, this.strictHelper);
}
2.1.1.3** 执行refresh() (核心)
该方法ClassPathXmlApplicationContext并未改写,即Spring的核心流程都是在父类AbstractApplicationContext中完成的,其他的实现类也仅仅是前期的准备工作不同。
this.refresh();
------------refresh方法--------------------------------------------------
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
//设置一些属性
this.prepareRefresh();
//创建BeanFactory,加载xml中配置的Bean以及xml中配置的功能
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//为BeanFactory设置一些属性
this.prepareBeanFactory(beanFactory);
try {
//空方法,用于扩展
this.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()-----prepareRefresh()
该方法主要设置了一个ApplicationEvent容器,同时设置关闭标志为false,开启标志为true。
protected void prepareRefresh() {
//开启计时
this.startupDate = System.currentTimeMillis();
//将关闭标志设置为false
this.closed.set(false);
//设置激活位为true
this.active.set(true);
if (this.logger.isInfoEnabled()) {
this.logger.info("Refreshing " + this);
}
//初始化属性源,空方法,留给子类扩展
this.initPropertySources();
//调用Environment的propertyResolver的validateRequiredProperties()
//用于验证所需要的属性是否准备好
this.getEnvironment().validateRequiredProperties();
//初始化一个存放ApplicationEvent的容器
this.earlyApplicationEvents = new LinkedHashSet();
}
refresh()-----obtainFreshBeanFacotry()(重点)
该方法主要过程如下:
主要逻辑在refreshBeanFactory (该方法用子类AbstractRefreshableApplicationContext的实现 )
主要作用就是创建一个BeanFactory,并加载BeanDefinitions到ApplicationContext中(XML中配置的)。
refreshBeanFactory:
- 创建一个DefaultListableBeanFactory,在这个过程中初始化父类。设置了一些属性,例如allowCircularReferences。
- this.customizeBeanFactory(beanFactory),不执行逻辑,留给子类扩展
- this.loadBeanDefinitions(beanFactory),这里调用的是子类AbstractXmlApplicationContext的实现,该方法会创建一个XmlBeanDefinitionReader,然后调用Reader的loadBeanDefinitions。此处注意,在创建XmlBeanDefinitionReader时会将第一步创建的BeanFactory传递进去,作为一个BeanDefinitionRegistry,当XmlBeanDefinitionReader读取到BeanDefinition后,会通过该registry注册到BeanFactory中。
- 调用Reader的loadBeanDefinitions其实是调用抽象父类(AbstractXmlApplication)的loadBeanDefinitions。
- AbstractXmlApplication的loadBeanDefinitions最终调用XmlBeanDefinitionReader的loadBeanDefinitions
- 最终调用 XmlBeanDefinitionReader 的 doLoadBeanDefinitions()方法完成加载(具体为7.8两步)
- 调用Document的doLoadCocument方法,使用DefaultDocumentLoader中的实现加载BeanDefinition
- 调用XmlBeanDefinitionReader 的registerBeanDefinitions将读取出来的BeanDefinition注册到BeanFactory。最终通过DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions完成注册。
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
--------------------------------obtainFreshBeanFactory-------------------------------
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//创建BeanFactory,加载BeanDefinitions
this.refreshBeanFactory();
//获取创建好的BeanFactory并返回
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
-------------1.refreshBeanFactory在AbstractApplicationContext的父类AbstractRefreshableApplicationContext中
protected final void refreshBeanFactory() throws BeansException {
//如果已经有BeanFactory了,则销毁并关闭
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
//创建一个DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
//设置序列化ID
beanFactory.setSerializationId(this.getId());
//2.定制BeanFactory,用于扩展,此处是不执行任何逻辑的
this.customizeBeanFactory(beanFactory);
//核心,加载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在创建 DefaultListableBeanFactory 的时候,会先创建其父类-----------
public AbstractAutowireCapableBeanFactory() {
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
this.parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
this.allowCircularReferences = true; //允许循环引用
this.allowRawInjectionDespiteWrapping = false;
this.ignoredDependencyTypes = new HashSet();
this.ignoredDependencyInterfaces = new HashSet();
this.factoryBeanInstanceCache = new ConcurrentHashMap(16);
this.filteredPropertyDescriptorsCache = new ConcurrentHashMap(256);
this.ignoreDependencyInterface(BeanNameAware.class);
this.ignoreDependencyInterface(BeanFactoryAware.class);
this.ignoreDependencyInterface(BeanClassLoaderAware.class);
}
--------------------3.核心方法loadBeanDefinitions(子类:AbstractXmlApplicationContext)----
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//定义一个XML文件的Reader解析XML文件,读取BeanDefinitions,在该过程中会将BeanFactory
//作为一个BeanDefinitionRegistry传到XmlBeanDefinitionReader的父类
//AbstractBeanDefinitionReader,作为其registry属性。
//后面XmlBeanDefinitionReader读取到BeanDefinition后要通过registry属性注册
//即将读取出来的BeanDefinition存入到BeanFactory中
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//设置Environment,这一步没怎么看懂,ApplicationContext中的Environment对象
//和Reader创建的Environment都是只含有系统变量和系统环境的。。为啥要覆盖一次???
beanDefinitionReader.setEnvironment(this.getEnvironment());
//将当前的对象设置为ResourceLoader,后面加载Resource会用到
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
this.loadBeanDefinitions(beanDefinitionReader);
}
-------------3.1 loadBeanDefinitions(beanDefinitionReader)方法---------------
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
//null
Resource[] configResources = this.getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//传入的xml文件
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
//调用Reader的loadBeanDefinitions加载配置文件
reader.loadBeanDefinitions(configLocations);
}
}
-------------4.XmlReader的loadBeanDefinitions(实际上是AbstractBeanDefinitionReader的方法)
//分别加载每一个配置文件(XmlBeanDefinitionReader)
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int counter = 0;
String[] var3 = locations;
int var4 = locations.length;
for(int var5 = 0; var5 < var4; ++var5) {
String location = var3[var5];
counter += this.loadBeanDefinitions(location);
}
//加载单个配置文件的函数(XmlBeanDefinitionReader)
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return this.loadBeanDefinitions(location, (Set)null);
}
//this.loadBeanDefinitions((Resource)resource)这里 该重载方法由子类XmlBeanDefinitionReader实现
//因为我们创建的实际类就是XmlBeanDefinitionReader
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
} else {
int loadCount;
if (!(resourceLoader instanceof ResourcePatternResolver)) {
Resource resource = resourceLoader.getResource(location);
loadCount = this.loadBeanDefinitions((Resource)resource);
//...其他语句
return loadCount;
} else {
try {
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
//核心,该方法由子类实现
loadCount = this.loadBeanDefinitions(resources);
//......其他语句
return loadCount;
} catch (IOException var10) {
throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var10);
}
}
}
}
------------------5. XmlBeanDefinitionReader的loadBeanDefinitions--------
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
//.....
Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
//....
//最终工作的语句
var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
//.....
---------------------------6. doLoadBeanDefinitions-------------
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
Document doc = this.doLoadDocument(inputSource, resource);
//将读取的BeanDefinition存入到BeanFactory
return this.registerBeanDefinitions(doc, resource);
}catch(...){
}//....
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
this.logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
//7.
this.doRegisterBeanDefinitions(root);
}
-------------------------8. DefaultBeanDefinitionDocumentReader
//在doRegisterBeanDefinitions调用this.parseBeanDefinitions(root, this.delegate);
// parseBeanDefinitions中调用this.parseDefaultElement(ele, delegate);
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, "bean")) {
this.processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}
//在processBeanDefinition中调用
//BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
//将BeanDefinition注册到BeanFactory中,BeanFactory实现是DefultListableBeanFactory
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
//.... 将BeanDefinition放入Map
this.beanDefinitionMap.put(beanName, beanDefinition);
}
------------------------完成资源加载---------------------------------
refresh()-----prepareBeanFactory(beanFacory)
该方法主要为BeanFactory设置一些属性,此时BeanFactory只含有我们在配置文件配置的那些Bean的BeanDefinition定义,再为其设置表示Environment的Bean及其他的Bean还有一些PostProcessor等
- 设置类加载器;
- 设置EL表达式解析器(Bean创建完成填充属性时使用)和属性注册解析器
- 利用BeanPostProcessor的特性给各种Aware接口的实现类注入ApplicationContext中对应的属性
- 设置各种Aware接口的实现类为忽略自动装配
- 设置这些类的具体装配实例(BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext)
- 如果BeanFactory中存在loadTimeWeaver的bean,那么需要添加动态织入功能
- 注册各种可用组件(environment,systemProperties,systemEnvironment)
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//设置类加载器
beanFactory.setBeanClassLoader(this.getClassLoader());
//设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//设置属性注册解析器PropertyEditor,即我们通过property文件动态设置bean属性
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
// 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,
//从而在Aware接口实现类中的注入applicationContext
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时,注入beanFactory
//防止有多个实例时,注入不知道注入哪一个,主要为了解决spring框架内部注入的问题
//如果是我们外部人员可以通过指定的方式来解决,spring内部则相当于在这里指定
//注入某个类型时具体要注入的类
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//注册一个BeanPostProcessor,负责在每个Bean初始化完成后判断是否是监听器,
//是的话注册到应用的事件多播器上
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//如果当前BeanFactory包含loadTimeWeaver Bean,
//说明存在类加载期织入AspectJ,则把当前BeanFactory交给类加载期BeanPostProcessor实现类
//LoadTimeWeaverAwareProcessor来处理,从而实现类加载期织入AspectJ的目的
if (beanFactory.containsBean("loadTimeWeaver")) {
//BeanPostProcessor在类初始化的时候起作用
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//注册当前容器环境environment组件Bean
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
//注册系统配置systemProperties组件Bean
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
//注册系统环境systemEnvironment组件Bean
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
}
refresh()-----postProcessBeanFactory(beanFactory)
空方法,主要是用来交给子类去扩展。SpringBoot启动时好像就重写了该方法。
负责给BeanFactory加一些定制的BeanFacotyPostProcessor。
refresh()-----invokeBeanFactoryPostProcessors(beanFactory)(重点)
执行所有注册的BeanFctoryPostProcessor,此处主要有ConfigurationClassPostProcessor,该类主要用于加载通过@Import,@Bean,@ComponentScan等注解加入的Bean。将我们没在配置文件,而是用注解注入的Bean加载到BeanFactory中。(即完成通过注解注入的那些Bean的扫描)
- invokeBeanFactoryPostProcessors(beanFactory)
- 匹配 PriorityOrder 的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry()方法
- 匹配 Order 的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry()方法
- 其余的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry()方法
- 所有的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory()方法
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
----------------------核心invokeBeanFactoryPostProcessors()------------------
//执行所有的BeanFactoryPostProcessor
/*
此处逻辑:从BeanFactory中找出所有BeanDefinitionRegistryPostProcessor
先找匹配PriorityOrder类型的(即在xml中配置了PriorityOrder属性),然后排序并执行postProcessBeanDefinitionRegistry。
再找匹配Order的,排序后执行postProcessBeanDefinitionRegistry。
最后执行所有剩下的其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。
执行通过函数invokeBeanDefinitionRegistryPostProcessors()完成。
--------------
最后把所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法执行
通过invokeBeanFactoryPostProcessors()
*/
//执行的主要方法是:invokeBeanDefinitionRegistryPostProcessors,
//主要是执行ConfigurationClassPostProCessor
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
//ConfigurationClassPostProCessor的processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//获取所有的beanName
List<BeanDefinitionHolder> configCandidates = new ArrayList();
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;
for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
//得到BeanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断是否解析过
if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
//判断是否为配置类
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//解析配置类
if (!configCandidates.isEmpty()) {
Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return i1 < i2 ? -1 : (i1 > i2 ? 1 : 0);
}
});
//是否单例
SingletonBeanRegistry singletonRegistry = null;
if (registry instanceof SingletonBeanRegistry) {
singletonRegistry = (SingletonBeanRegistry)registry;
//....
}
}
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
HashSet alreadyParsed = new HashSet(configCandidates.size());
do {
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
}
//解析出来的类,注册到容器中
this.reader.loadBeanDefinitions(configClasses);
//.....
}
refresh()-----registerBeanPostProcessors(beanFactory)
注册BeanPostProcessor。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
-----------------------------------------------
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//获取所有的BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//存放实现PriorityOrder接口的后置处理器
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<BeanPostProcessor> internalPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
List<String> nonOrderedPostProcessorNames = new ArrayList();
String[] var8 = postProcessorNames;
int var9 = postProcessorNames.length;
//将所有的后知处理器按照优先级分别放入不同的容器
String ppName;
BeanPostProcessor pp;
for(int var10 = 0; var10 < var9; ++var10) {
ppName = var8[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
pp = (BeanPostProcessor)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);
}
}
//把实现PriorityOrder的加入到容器中
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();
while(var14.hasNext()) {
String ppName = (String)var14.next();
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//把所有实现Order接口的PostProcessor加入到容器中
sortPostProcessors(beanFactory, orderedPostProcessors);
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();
while(var17.hasNext()) {
ppName = (String)var17.next();
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//注册我们普通的没有实现任何排序接口的
registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
//注册MergedBeanDefinitionPostProcessor类型的后置处理器
sortPostProcessors(beanFactory, internalPostProcessors);
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
//注册ApplicationListenerDetector应用监听器探测器的后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
refresh()-----initMessageSource()
国际化的一些配置,先不管
refresh()-----initApplicationEventMulticaster()
初始化事件多播器,事件多播器采用典型的设计模式就是观察者模式,多播器作为的是一个被观察者。
作用就是维护所有的监听者对象,spring发生事件后,会获取多播器,然后通过多播器发送给所有的监听该事件的监听者。
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
//判断容器中是否包含了applicationEventMulticaster事件多播器组件
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {//容器中没有的话,直接new一个并且注入到容器中
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]");
}
}
}
refresh()-----onRefresh()(重点)
但是Spring并未实现该方法,留给子类扩展,比如SpringBoot在该方法中实现spring容器启动的时候启动Tomcat服务器
refresh()-----registerListeners()
将事件监听器注册到事件多播器上。
protected void registerListeners() {
//取出所有的事件监听器
Iterator var1 = this.getApplicationListeners().iterator();
while(var1.hasNext()) {
//将所有监听器注册到事件多播器上
ApplicationListener<?> listener = (ApplicationListener)var1.next();
this.getApplicationEventMulticaster().addApplicationListener(listener);
}
//获取所有的监听器对象
String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
String[] var7 = listenerBeanNames;
int var3 = listenerBeanNames.length;
for(int var4 = 0; var4 < var3; ++var4) {
String listenerBeanName = var7[var4];
//将监听器的Name注册到事件多播器上
this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//获取早期事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
//广播所有的早期事件
if (earlyEventsToProcess != null) {
Iterator var9 = earlyEventsToProcess.iterator();
while(var9.hasNext()) {
ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
refresh()-----finishBeanFactoryInitialization(beanFactory)(重点)
该处实例化所有非懒加载的单例Bean对象。前面只是将XML或者注解配置的Bean读取到容器中,并封装为一个个的BeanDefinition,但并未实例化。实例化是在这里解决的。
https://www.cnblogs.com/toby-xu/p/11333479.html
refresh()-----finishRefresh()
最后一步,发布刷新事件(ContextRefreshedEvent)
protected void finishRefresh() {
//初始化声明周期处理器
this.initLifecycleProcessor();
//启动容器中所有Lifecycle类型的Bean
this.getLifecycleProcessor().onRefresh();
//发布ContextRefreshedEvent事件
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}
2.1.2 使用
2.2通过注解加载的方式启动
大同小异,最大的不同是在创建BeanFactory时仅仅实现创建工厂,而不会去扫描XML文件了。
AnnotationConfigApplicationContext ioc2 = new AnnotationConfigApplicationContext(AppConfig.class);
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
public AnnotationConfigApplicationContext() {
//初始化注解读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
//扫描并加载classpath下的Bean,加载的Bean有@Respository、@Service、@Controller
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
//剩下的是调用refresh(),不过注意,创建BeanFactory时调用refreshBeanFactory()
//是父类GenericApplicationContext的,而不是AbstractApplicationContext。所以不会加载XML配置文件
详情,可以参照博客:
https://www.cnblogs.com/toby-xu/p/11324776.html
本文地址:https://blog.csdn.net/sinat_38705282/article/details/110007518
推荐阅读
-
一步步教你整合SSM框架(Spring MVC+Spring+MyBatis)详细教程
-
Spring mvc整合tiles框架的简单入门教程(maven)
-
spring mvc 组合mybatis框架实例详解
-
Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(图文)
-
IOS框架Spring常用的动画效果
-
使用maven整合Spring+SpringMVC+Mybatis框架详细步骤(图文)
-
详解JAVAEE——SSH三大框架整合(spring+struts2+hibernate)
-
什么是spring框架的aop(spring中aop的概念)
-
java spring框架入门(java后端框架排名)
-
Spring框架中 @Autowired 和 @Resource 注解的区别