博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring boot 源码分析(二) 配置文件加载2
阅读量:6452 次
发布时间:2019-06-23

本文共 3161 字,大约阅读时间需要 10 分钟。

hot3.png

一、前言

上篇讲到了spring boot 通过SpringFactoriesLoader.loadFactoryNames进行加载工厂实例名称列表。本篇是接着上篇继续从源码讲解spring boot加载配置文件的流程,

二、代码解读

private 
Collection
getSpringFactoriesInstances(Class
type, Class
[] parameterTypes, Object... args) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates //使用name来保证唯一,防止重复 Set
names = new LinkedHashSet<>( SpringFactoriesLoader.loadFactoryNames(type, classLoader)); List
instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }

既然他加载完工厂实例名称列表了,那么他如何初始化呢。我们继续往下看,他有个

createSpringFactoriesInstances()

//用来创建spring工厂实例private 
List
createSpringFactoriesInstances(Class
type, Class
[] parameterTypes, ClassLoader classLoader, Object[] args, Set
names) { List
instances = new ArrayList<>(names.size());//创建实例list,用来装创建好的实例 for (String name : names) { try { Class
instanceClass = ClassUtils.forName(name, classLoader);//创建没有被链接的类,此处底层用到了 ClassLoader.loadClass 关于它和 Class.forName的区别 可以参考https://www.cnblogs.com/suibianle/p/6676215.html Assert.isAssignable(type, instanceClass);//判断instanceClass是否是type类型 Constructor
constructor = instanceClass .getDeclaredConstructor(parameterTypes);//获取instanceClass构造 T instance = (T) BeanUtils.instantiateClass(constructor, args);//实例化 instances.add(instance); } catch (Throwable ex) { throw new IllegalArgumentException( "Cannot instantiate " + type + " : " + name, ex); } } return instances; }

经过此方法后,关于type类型的工厂实例就初始化完成了。

那么我们上篇文章讲到,spring boot 在创建完工厂实例后,他又进行了注册监听器,他注册监听干什么事情了呢?我们看一下,研究研究。

package org.springframework.boot;public class SpringApplication {public SpringApplication(ResourceLoader resourceLoader, Class
... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.webApplicationType = deduceWebApplicationType(); setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass();}}

我们看一下setListeners();

他内部也进行了创建工厂实例。这里我们就不再进行赘述了。上述文章已经针对创建工厂实例进行详细的描述了。

我们看setListeners内部是如何实现的,他拿这些工厂实例做什么了?

//Sets the ApplicationListeners that will be applied to the SpringApplication and registered with the ApplicationContext.//解释一下,他大致意思就是说设置这些集合主要是应用于SpringApplication并且注册到ApplicationContextpublic void setListeners(Collection
> listeners) { this.listeners = new ArrayList<>(); this.listeners.addAll(listeners);}

我们可以看到,他内部其实就是将这些工厂实例加入到了一个大的listeners集合中,并没有做其他操作。可能以后他会用到这个listeners集合。

ok,本章关于初始化配置就讲到这里,下一篇会继续解读Spring Boot的源码,来与大家一起分享

转载于:https://my.oschina.net/u/1178126/blog/1820854

你可能感兴趣的文章
明年计划
查看>>
ORACLE功能GREATEST功能说明具体实例
查看>>
DataGridView 输入数据验证格式(实例)
查看>>
HDOJ 2151
查看>>
Foundation框架 - 快速创建跨平台的网站页面原型
查看>>
Intel 82599网卡异常挂死原因
查看>>
open-falcon
查看>>
三菱plc输出指示灯不亮怎么办(转载)
查看>>
doc2vec使用说明(一)gensim工具包TaggedLineDocument
查看>>
App测试中ios和Android的区别
查看>>
java.lang.NullPointerException&com.cb.action.LoginAction.execute(LoginAction.java:48)
查看>>
理解Docker :Docker 网络
查看>>
通过Application存取公共数据比如登录信息等..
查看>>
intellij maven配置与使用
查看>>
SpringMVC文件下载与JSON格式
查看>>
Q:图像太大,在opencv上显示不完全
查看>>
修正锚点跳转位置 避免头部fixed固定部分遮挡
查看>>
Dubbo序列化多个CopyOnWriteArrayList对象变成同一对象的一个大坑!!
查看>>
linux下ping不通的解决方法
查看>>
利用ItextPdf、core-renderer-R8 来生成PDF
查看>>