spring boot 加载配置文件的机制是其核心功能之一,它通过一系列源码实现从不同来源加载配置,并支持灵活的配置管理。以下是 spring boot 加载配置文件的源码解析及其实现原理的详细说明。(下述两段是加载配置文件的源码片段)
public springapplication(resourceloader resourceloader, class<?>... primarysources) {
this.sources = new linkedhashset();
this.bannermode = mode.console;
this.logstartupinfo = true;
this.addcommandlineproperties = true;
this.addconversionservice = true;
this.headless = true;
this.registershutdownhook = true;
this.additionalprofiles = collections.emptyset();
this.iscustomenvironment = false;
this.lazyinitialization = false;
this.applicationcontextfactory = applicationcontextfactory.default;
this.applicationstartup = applicationstartup.default;
this.resourceloader = resourceloader;
assert.notnull(primarysources, "primarysources must not be null");
this.primarysources = new linkedhashset(arrays.aslist(primarysources));
//1.推测web应用类型(none reactive servlet)
this.webapplicationtype = webapplicationtype.deducefromclasspath();
//2.从spring.factories中获取bootstrapregistryinitializer对象
this.bootstrapregistryinitializers =
this.getbootstrapregistryinitializersfromspringfactories();
//3.从spring.factories中获取applicationcontextinitializer对象
this.setinitializers(this.getspringfactoriesinstances(applicationcontextinitializer.class));
//4.从spring.factories中获取applicationlistener对象
this.setlisteners(this.getspringfactoriesinstances(applicationlistener.class));
//5.推测出main类 (main()方法所在的类)
this.mainapplicationclass = this.deducemainapplicationclass();
}public configurableapplicationcontext run(string... args) {
stopwatch stopwatch = new stopwatch();
stopwatch.start();
defaultbootstrapcontext bootstrapcontext = this.createbootstrapcontext();
configurableapplicationcontext context = null;
this.configureheadlessproperty();
/**从spring.factories中获取springapplicationrunlisteners 对象
* 默认会拿到一个eventpublishingrunlistener ,他会启动过程的各个阶段发布对应的事件
**/
springapplicationrunlisteners listeners = this.getrunlisteners(args);
listeners.starting(bootstrapcontext, this.mainapplicationclass);
try {
//将run()的参数封装为defaultapplicationarguments对象
applicationarguments applicationarguments = new defaultapplicationarguments(args);
//配置文件的入口
configurableenvironment environment = this.prepareenvironment(listeners, bootstrapcontext, applicationarguments);
this.configureignorebeaninfo(environment);
banner printedbanner = this.printbanner(environment);
//根据应用类型创建spring容器
context = this.createapplicationcontext();
context.setapplicationstartup(this.applicationstartup);
this.preparecontext(bootstrapcontext, context, environment, listeners, applicationarguments, printedbanner);
//刷新spring容器, 会解析配置类 扫描 启动webserver
this.refreshcontext(context);
this.afterrefresh(context, applicationarguments);
stopwatch.stop();
if (this.logstartupinfo) {
(new startupinfologger(this.mainapplicationclass)).logstarted(this.getapplicationlog(), stopwatch);
}
listeners.started(context);
//调用applicationarguments 和commandlinerunner
this.callrunners(context, applicationarguments);
} catch (throwable var10) {
this.handlerunfailure(context, var10, listeners);
throw new illegalstateexception(var10);
}
try {
listeners.running(context);
return context;
} catch (throwable var9) {
this.handlerunfailure(context, var9, (springapplicationrunlisteners)null);
throw new illegalstateexception(var9);
}
}
1. spring boot 加载配置文件的整体流程
spring boot 加载配置文件的流程可以分为以下几个步骤:
初始化
environment:在应用启动时,创建并初始化environment对象。加载默认配置文件:从
application.properties或application.yml加载配置。加载 profile 特定的配置文件:根据激活的 profile 加载
application-{profile}.properties或application-{profile}.yml。加载外部化配置:从命令行参数、环境变量、jndi 等外部来源加载配置。
合并配置:将所有配置来源合并到
environment中,供应用程序使用。
2. 源码解析
以下是 spring boot 加载配置文件的核心源码解析。
2.1 springapplication.run()
spring boot 应用的启动入口是 springapplication.run() 方法。在这个方法中,会初始化 environment 并加载配置文件。
源码位置:org.springframework.boot.springapplication
public configurableapplicationcontext run(string... args) {
// ...
configurableenvironment environment = prepareenvironment(listeners, applicationarguments);
// ...
}说明:
prepareenvironment()方法负责创建和配置environment对象。
2.2 prepareenvironment()
prepareenvironment() 方法会调用 configureenvironment() 来加载配置文件。
源码位置:org.springframework.boot.springapplication
private configurableenvironment prepareenvironment(springapplicationrunlisteners listeners, applicationarguments applicationarguments) {
// 创建 environment 对象
configurableenvironment environment = getorcreateenvironment();
// 配置 environment,加载配置文件
configureenvironment(environment, applicationarguments.getsourceargs());
// 触发环境准备事件
listeners.environmentprepared(environment);
// 将 environment 绑定到 springapplication
bindtospringapplication(environment);
return environment;
}说明:
getorcreateenvironment():根据应用类型(web 或非 web)创建standardenvironment或standardservletenvironment。configureenvironment():加载配置文件和其他外部化配置。
2.3 configureenvironment()
configureenvironment() 方法会调用 configurepropertysources() 和 configureprofiles() 来加载配置文件和激活 profile。
源码位置:org.springframework.boot.springapplication
protected void configureenvironment(configurableenvironment environment, string[] args) {
configurepropertysources(environment, args);
configureprofiles(environment, args);
}说明:
configurepropertysources():加载命令行参数、默认配置文件等。configureprofiles():设置激活的 profile。
2.4 configfileapplicationlistener
configfileapplicationlistener 是 spring boot 加载配置文件的核心类。它监听 applicationenvironmentpreparedevent 事件,并加载 application.properties 或 application.yml 文件。
源码位置:org.springframework.boot.context.config.configfileapplicationlistener
public void onapplicationevent(applicationevent event) {
if (event instanceof applicationenvironmentpreparedevent) {
onapplicationenvironmentpreparedevent((applicationenvironmentpreparedevent) event);
}
}说明:
onapplicationenvironmentpreparedevent():在环境准备完成后触发,加载配置文件。
2.5 loader.load()
loader 是 configfileapplicationlistener 的内部类,负责实际加载配置文件。
源码位置:org.springframework.boot.context.config.configfileapplicationlistener.loader
void load() {
for (string location : getsearchlocations()) {
for (string name : getsearchnames()) {
load(location, name);
}
}
}说明:
getsearchlocations():获取配置文件的搜索路径(如classpath:/、file:./config/等)。getsearchnames():获取配置文件的名称(如application)。load(location, name):从指定路径加载配置文件。
2.6 propertysourcesloader
propertysourcesloader 负责将配置文件内容加载到 propertysource 中。
源码位置:org.springframework.boot.env.propertysourcesloader
public propertysource<?> load(resource resource) throws ioexception {
if (resource.getfilename().endswith(".yml")) {
return loadyaml(resource);
} else {
return loadproperties(resource);
}
}说明:
loadyaml():加载 yaml 格式的配置文件。loadproperties():加载 properties 格式的配置文件。
2.7 profile 的加载
spring boot 支持通过 profile 加载不同的配置文件。profiles 和 profilepropertysource 负责处理 profile 相关的配置。
源码位置:org.springframework.core.env.profiles
public static profiles of(string... profiles) {
return new profiles() {
@override
public boolean matches(predicate<string> predicate) {
// ...
}
};
}说明:
profiles:管理 profile 的激活状态。profilepropertysource:根据激活的 profile 加载特定的配置文件。
3.spring boot配置文件的实现原理
spring boot 加载配置文件的实现原理可以总结为以下几点:
- 多来源加载:支持从类路径、外部目录、环境变量、命令行参数等多种来源加载配置。
- 优先级机制:后加载的配置会覆盖先加载的配置,命令行参数的优先级最高。
- profile 支持:通过
spring.profiles.active指定激活的 profile,加载对应的配置文件。 - 外部化配置:支持从外部文件、环境变量、jndi 等加载配置,适用于云原生和容器化部署。
4. 示例:spring boot 加载配置文件的流程
以下是一个完整的示例,展示 spring boot 如何加载配置文件。
4.1 默认配置文件
application.properties:
server.port=8080 spring.profiles.active=dev
4.2 profile 特定的配置文件
application-dev.properties:
server.port=8081
4.3 java 代码
@restcontroller
public class mycontroller {
@value("${server.port}")
private string port;
@getmapping("/port")
public string getport() {
return "server port: " + port;
}
}4.4 运行结果
如果激活的 profile 是
dev,则server.port的值为8081。如果没有激活 profile,则
server.port的值为8080。
5. 总结
spring boot 加载配置文件的机制非常灵活,支持多来源、多格式的配置加载。通过 environment、propertysource、configfileapplicationlistener 等核心类和组件,spring boot 实现了配置文件的加载、合并和优先级管理。理解这些源码和机制,可以帮助我们更好地使用和扩展 spring boot 的配置功能。
到此这篇关于springboot加载配值文件的实现步骤的文章就介绍到这了,更多相关springboot加载配值文件内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论