1. preparecontext源码:
``` private void preparecontext(configurableapplicationcontext context, configurableenvironment environment, springapplicationrunlisteners listeners, applicationarguments applicationarguments, banner printedbanner) { //注入环境属性 context.setenvironment(environment); //上下文后置处理 this.postprocessapplicationcontext(context); //完善初始化类的属性 this.applyinitializers(context); //发送监听事件 listeners.contextprepared(context); //日志 if (this.logstartupinfo) { this.logstartupinfo(context.getparent() == null); this.logstartupprofileinfo(context); } //注册传入的配置参数为bean,这里将传入的参数封装成applicationarguments,内部类似命令行 configurablelistablebeanfactory beanfactory = context.getbeanfactory(); beanfactory.registersingleton(springapplicationarguments, applicationarguments); //banner打印 if (printedbanner != null) { beanfactory.registersingleton(springbootbanner, printedbanner); } //这里默认情况下bean定义不允许重复 if (beanfactory instanceof defaultlistablebeanfactory) { ((defaultlistablebeanfactory)beanfactory).setallowbeandefinitionoverriding(this.allowbeandefinitionoverriding); } //默认不开启延迟加载 if (this.lazyinitialization) { context.addbeanfactorypostprocessor(new lazyinitializationbeanfactorypostprocessor()); } //获取全部的资源 //这里获取了启动类的资源和 当前springapplication中的source资源。 //到目前来说实际上只有启动类资源 set<object> sources = this.getallsources(); assert.notempty(sources, sources must not be empty); this.load(context, sources.toarray(new object[0])); listeners.contextloaded(context);}```
老样子进行逐个分析。但看这个方法并不复杂,整体上对上下文和工厂类进行配置的完善。
1.1 postprocessapplicationcontext 方法源码:
protected void postprocessapplicationcontext(configurableapplicationcontext context) { // 是否自定义bean名称生成类 if (this.beannamegenerator != null) { context.getbeanfactory().registersingleton(org.springframework.context.annotation.internalconfigurationbeannamegenerator, this.beannamegenerator); } //是否指定类加载器 if (this.resourceloader != null) { if (context instanceof genericapplicationcontext) { ((genericapplicationcontext)context).setresourceloader(this.resourceloader); } if (context instanceof defaultresourceloader) { ((defaultresourceloader)context).setclassloader(this.resourceloader.getclassloader()); } } //是否添加数据转换器 //在初始化环境对象的时候也有用到,这里可以直接通过 context.getenvironment().getconversionservice()获取到 if (this.addconversionservice) { context.getbeanfactory().setconversionservice(applicationconversionservice.getsharedinstance()); } }
1.2 applyinitializers完善与applicationcontextinitializer接口相关的对象属性。这些对象在this.initializers中,早在springapplication初始化的时候就已经加载。通过已经初始化好的上下文对相关类进行完善。调用接口的initialize方法。
1.3 load源码:
protected void load(applicationcontext context, object[] sources) { if (logger.isdebugenabled()) { logger.debug(loading source + stringutils.arraytocommadelimitedstring(sources)); } //构建一个bean定义的加载器 beandefinitionloader loader = createbeandefinitionloader(getbeandefinitionregistry(context), sources); if (this.beannamegenerator != null) { loader.setbeannamegenerator(this.beannamegenerator); } if (this.resourceloader != null) { loader.setresourceloader(this.resourceloader); } if (this.environment != null) { loader.setenvironment(this.environment); } //将资源加载成bean loader.load(); } void load() { for (object source : this.sources) { load(source); } } //按资源类型分别进行加载, private void load(object source) { assert.notnull(source, source must not be null); if (source instanceof class<?>) { load((class<?>) source); return; } if (source instanceof resource) { load((resource) source); return; } if (source instanceof package) { load((package) source); return; } if (source instanceof charsequence) { load((charsequence) source); return; } throw new illegalargumentexception(invalid source type + source.getclass()); }
主要加载了springapplication内初始化的资源,包括我们的启动类xxapplication将会被注册成bean。
以上就是springboot怎么完善上下文加载器的详细内容。