SpringBoot启动选择ApplicationContext

编程

  • 常规方式
    ConfigurableApplicationContext context = SpringApplication.run(CreditBootstrap.class, args);
  • 可设置参数
    ConfigurableApplicationContext context  = new SpringApplicationBuilder(CbmsManageApp.class).web(WebApplicationType.SERVLET).run(args);

返回一个ConfigurableApplicationContext对象

  • org.springframework.context.annotation.AnnotationConfigApplicationContext
  • org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext 在支持SERVLET模式下启用。
    (不同版本不同,当前是spring-boot-2.1.5.RELEASE)

加载配置

启动先加载bootstrap.yml,从远端获取application.yml覆盖本地。
若指定scanBasePackages(包及子包下)则扫描指定路径,否则默认加载启动main方法类的包路径。

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }, scanBasePackages={"com.noob.mics"})

配置化启用装配

#调度中心配置

xxl:

job:

enable: true

@Configuration

@ConditionalOnProperty(prefix = "xxl.job", name = "enable", havingValue = "true" , matchIfMissing = false)

public class XxlJobConfiguration {

  • matchIfMissing:  缺少该配置属性时是否可以加载。如果为true,没有该配置属性时也会正常加载;反之则不会生效
  • havingValue:  与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置。  如果havingValue未指定值,默认情况下在属性配置中设置的值为true则生效(如上配置),false则不生效。

@ConfigurationProperties 需要与@EnableConfigurationProperties 合用。 如果@ConfigurationProperties没有与@Component并用,则@EnableConfigurationProperties需要额外设置value的值来指定属性类

@EnableConfigurationProperties({ServerProperties.class})

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)

public class ServerProperties {

ApplicationContext的选择

下文以 spring-boot-2.1.5.RELEASE 为例。不同版本下的具体实现与构建的ApplicationContext种类都不一样。

重点关注 WebApplicationType  SpringApplication

WebApplicationType.deduceFromClasspath() 决定容器环境类型  (默认是:WebApplicationType.SERVLET

​private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet",

"org.springframework.web.context.ConfigurableWebApplicationContext" };

private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";

private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";

private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";

private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";

private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";

static WebApplicationType deduceFromClasspath() {

if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)

&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)

&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {

return WebApplicationType.REACTIVE;

}

for (String className : SERVLET_INDICATOR_CLASSES) {

if (!ClassUtils.isPresent(className, null)) {

return WebApplicationType.NONE;

}

}

return WebApplicationType.SERVLET;

}

SpringApplication.run() -> SpringApplication.createApplicationContext() : 依据WebApplicationType类型来选择最终的ContextClass。

/**

* 非SERVLET模式默认

*/

public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context.annotation.AnnotationConfigApplicationContext";

/**

* SERVLET模式下默认

*/

public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext";

/**

* The class name of application context that will be used by default for reactive web

* environments.

*/

public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";

protected ConfigurableApplicationContext createApplicationContext() {

Class<?> contextClass = this.applicationContextClass;

if (contextClass == null) {

try {

switch (this.webApplicationType) {

case SERVLET:

contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);

break;

case REACTIVE:

contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);

break;

default:

contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);

}

}

catch (ClassNotFoundException ex) {

throw new IllegalStateException(

"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);

}

}

return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);

}

如果有需要设置启动的相关属性,可以通过SpringApplicationBuilder的contextClass、web 等方法来指定SpringApplication的内部变量值

public SpringApplicationBuilder web(WebApplicationType webApplicationType) {

     this.application.setWebApplicationType(webApplicationType);

     return this;

}

public SpringApplicationBuilder contextClass(

         Class<? extends ConfigurableApplicationContext> cls) {

     this.application.setApplicationContextClass(cls);

     return this;

}

public void setBanner(Banner banner) {

this.banner = banner;

}

... ...

 

以上是 SpringBoot启动选择ApplicationContext 的全部内容, 来源链接: utcz.com/z/516372.html

回到顶部