关于SpringBoot的自动配置和启动过程

一、简介

Spring Boot简化了Spring应用的开发,采用约定大于配置的思想,去繁从简,很方便就能构建一个独立的、产品级别的应用。

1.传统J2EE开发的缺点

开发笨重、配置繁多复杂、开发效率低下、部署流程复杂、第三方技术集成难度大。

2.SpringBoot的优点

  • 快速重建独立运行的Spring项目以及与主流框架集成。
  • 使用嵌入式的Servlet容器,应用无需打成WAR包
  • starters自动依赖与版本控制
  • 大量的自动配置、简化开发,也可以修改其默认值
  • 无需配置XML,无代码生成
  • 准生产环境的运行时应用监控
  • 与云计算的天然继承

3.SpringBoot helloworld说明

1.starters
  • SpringBoot为我们提供了简化企业级开发绝大多数场景的starters pom(启动器),只要引入了相应场景的starters pom,相关技术的绝大部分配置将会消除(字段配置),从而简化我们的开发。业务中我们就会使用到SpringBoot为我们字段配置的Bean。
  • 这些starters几乎涵盖了javaee所有常用场景,SpringBoot对这些场景依赖的jar也做了严格的测试和版本控制。
  • spring-boot-dependencies里面定义了jar包的版本。
2.入口类和@SpringBootApplication
  • 程序从main方法开始运行。
  • 使用SpringApplication.run()加载主程序类
  • 主程序类需标注@SpringBootApplication
  • @EnableAutoConfiguration是核心注解
  • @Import导入所有的自动配置场景
  • @AutoConfigurationPackage定义默认的包扫描规则。
  • 程序启动扫描主程序类所在的包以及下面所有子包的组件
3.自动配置

自动配置xxxAutoConfiguration

  • SpringBoot中存现大量的这些类,这些类的作用就是帮我们进行自动装配
  • 它会将这个场景需要的所有组件都注册到容器中,并配置好
  • 他们在类路径下的META-INF/spring.factories文件中
  • spring-boot-autoconfigure.jar中包含了所有场景的字段配置类代码
  • 这些自动配置类是SpringBoot进行自动装配的关键。

二、SpringBoot配置

1.配置文件

  • SpringBoot使用一个全局的配置文件。配置文件名是固定的。
    -application.properties或者application.yml

  • 配置文件放在src/main/resources目录或者类路径/config下。

  • 全局配置文件的作用是对一些默认配置进行修改

2.配置文件值注入

  • @Value和@ConfigurationProperties为属性注入值进行对比
对比点 @ConfigurationProperties @Value
功能 批量注入配置文件中的属性 一个个指定
松散绑定(松散语法) 支持 不支持
SpEL 不支持 支持
JSR303数据校验 支持 不支持
复杂类型封装 支持 不支持
  • 属性名匹配规则
    -person.firstName 使用标准方式
    -person.first-name 使用-
    -person.first_name 使用_
    -PERSON_FIRST_NAME 推荐系统属性使用这种写法

  • @PropertySource
    加载指定的配置文件

  • ConfigurationProperties
    -与@Bean结合为属性赋值
    -与@PropertySource(只能用于properties文件)结合读取指定文件。

  • ConfigurationProperties Validation
    -支持JSR303进行配置文件值校验。


@Component
@PropertySource(value={
   "classpath:person.properties"})
@ConfigurationProperties(prefix="person")
@Validated
public class Person{
   
    @Email
    @Value("${person.email}")
    private String email;
}
  • ImportResource读取外部配置文件

3.配置文件占位符

  • RandomValuePropertySource
    配置文件中可以使用随机数
    -${random.value}
    -${random.int}
    -${random.long}
    -${random.int(10)}
    -${random.int[1024,65536]}

  • 属性配置占用符
    -可以在配置文件中引用前面配置过的属性(Y优先级前面配置过的这里都可以使用)。
    -${ app.name:默认值}来指定找不到属性时的默认值。

app.name=MyApp    
app.description=${app.name} is a SpringBoot Application

4.profile

profile是Spring对不同环境提供不同配置功能的支持,可以通过激活指定参数的方式快速切换环境。

1.多profile文件形式
  • 格式:application-{profile}.properties/yml
    application-dev.properties、application-prod.properties
2.多profile文档块模式
spring.profiles.active=prod #激活指定配置
spring.profiles=prod
server.port=80
# default表示未指定时的默认配置
spring.profiles=default
server.port=8080

3.激活方式
  • 命令行:–spring.profiles.active=dev
  • 配置文件:spring.profiles.active=dev
  • jvm参数:-Dspring.profiles.active=dev

5.配置文件加载位置

SpringBoot启动会扫描一下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件。
- file:./config/
- file:./
- classpath:/config/
-classpath:/
-以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。
-可以通过配置spring.config.location来改变默认配置。

6.外部配置加载顺序

  1. 命令行参数
  2. 来自java:comp/env的JNDI属性
  3. Java系统属性(System.getProperties())
  4. 操作系统环境变量
  5. RandomValuePropertySource配置的random.*属性值
  6. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  7. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  8. jar包外部的application.properties或application.yml(不带spring.profile)配置文件
  9. jar包内部的application.properties或application.yml(不带spring.profile)配置文件
  10. @Configuration注解类上的@PropertySource。
  11. 通过SpringApplication.setDefaultproperties指定的默认属性。

7.自动配置原理

1.SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration
2.@EnableAutoConfiguration作用
  • 利用EnableAutoConfigurationImportSelector给容器中导入一些组件。
  • 将类路径小META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到了容器中。
3.@Conditional派生注解
@Conditional扩展注解 作用(判断是否满足当期指定条件)
@ConditionalOnJava 系统的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean
@ConditionalOnMissingBean 容器中不存在指定Bean
@ConditionalOnExpression 满足SpEL表达式指定
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMissingClass 容器中没有指定类
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty 系统中指定的属性是否有指定的值
@ConditionalOnResource 类路径下是否存在指定资源文件
@ConditionalOnWebApplication 当前是web环境
@ConditionalOnNotWebApplication 当前不是web环境
@ConditionalOnJndi JNDI存在指定项
  • 作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效。

三、SpringBoot与日志

1.日志框架

市场上存在非常多的日志框架,JUL(java.util.logging)、JCL(Apache Commons Logging)、Log4J、Log4J2、Logback、SLF4j、jboss-logging等。

  • SpringBoot早框架内部使用JCL。spring-boot-starter-logging采用了slf4j+logback的形式,SpringBoot也能自动配置(jul、log4j2、logback)并简化配置。
日志门面 日志实现
JCL、SLF4J、jboss-logging log4j、JUL、Log4j2、Logback
日志系统 配置文件
Logback logback-spring.xml、logback-spring.groovy、logback.xml或logback.groovy
Log4j2 log4j2-spring.xml、log4j2.xml
JUL logging.properties

在这里插入图片描述

  • 总结:
    1.SpringBoot底层也是使用slf4j+logback的方式进行日志记录。
    2.SpringBoot也把其他的日志都替换成了slf4j。
    3.如果要引入其他日志框架,要排除Spring框架的commons-logging依赖。

四、Web开发

1.SpringBoot对静态资源的映射规则

  • 所有/webjars/**,都去classpath:/META-INF/resources/webjars/ 下面找资源。
  • “/**” 访问当前项目的任何资源,都去(静态资源的文件夹)找映射。
  • 欢迎页;静态资源文件夹下的所有index.html页面,被"/**" 映射。
  • 所有的 **/favicon.ico都是在静态资源文件下找。

2.SpringMVC自动配置

1.SpringMVC auto-configuration

SpringBoot对SpringMVC的默认配置(WebMvcAutoConfiguration)如下:

  • 包含了ContentNegotiatingViewResolver和BeanNameViewResolver。

    • 自动配置了ViewResolver
    • ContentNegotiatingViewResolver:组合所有的视图解析器
  • 支持静态资源,包括支持Wenjars

  • 静态首页访问

  • 支持favicon.ico

  • 自动注册了Converter、GenericConverter、Formatter。

    • Converter:转换器。
    • Formatter:格式化器
  • 支持HttpMessageConverters

    • HttpMessageConverter:SpringMVC用来转换Http请求和响应。
    • HttpMessageConverters:从容器中确定,获取所有的HttpMessageConverter;
  • 自动注入MessageCodesResolver,定义错误码生成规则。

  • 自动使用ConfigurableWebBindingInitializer。

2.扩展SpringMVC

编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型,不能标注@EnableWebMvc注解

@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
   

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
   
        registry.addViewController("/desperado").setViewName("success");
    }
}

原理

  1. WebMvcAutoConfiguration是SpringMVC的自动配置类。
  2. 在做其他自动配置时会导入。
  3. 容器中所有的WebMvcConfigurer都会一起被注册。
  4. 我们自定义的配置类也会被调用。

3.全面接管SpringMVC

如果想要使SpringMVC的自动配置失效,只需要在我们自定义的配置类中添加@EnableWebMvc注解即可。

@EnableWebMvc
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
   

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
   
        registry.addViewController("/desperado").setViewName("success");
    }
}

原理

  1. @EnableWebMvc的注解
@Import(DelegatingWebMvcConfiguation.class)
public @interface EnableWebMvc{
   }
  1. DelegatingWebMvcConfiguation
@Configuration
public class DelegatingWebMvcConfiguation extend WebMvcConfigurationSupport{
   }
  1. WebMvcAutoConfiguration
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({
   Servlet.class,DispatcherServlet.class,
                      WebMvcConfigurerAdapter.class})
//容器中没有这个组件,这个自动配置类才会生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({
   DispatcherServletAutoConfiguration.class,
                ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration{
   }
  1. @EnableWebMvc会将WebMvcConfigurationSupport组件导入进来。
  2. 导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能。

4.修改默认配置

  1. SpringBoot在自动配置很多组件的时候,显卡容器中有没有用户自己配置的(@Bean 、@Component),如果有就用用户配置的,如果没有,才会进行自动配置;如果某些组件可以有多个,将用户配置的和自己默认的组合起来。
  2. 在SpringBoot中有许多的xxxConfigurer帮助我们进行扩展配置
  3. 在SpringBoot中有许多的xxxCustomizer帮助我们进行定制配置

5.默认访问首页

使用自定义WebMvcConfigurationAdapter进行配置

//使用WebMvcConfigurationAdapter可以扩展SpringMVC的功能
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
   

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
   
        //浏览器发送/desperado 请求来到success
        registry.addViewController("/desperado").setViewName("success");
    }

    //所有的webMvcConfigurerAdapter组件都会一起起作用
    @Bean   //将组件注册到容器
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
   
        WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
   
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
   
                //配置默认路径的页面
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/index.html").setViewName("login");
            }
        };
        return adapter;
    }
}

6.国际化

1.编写国际化配置文件
编写不同语言的配置文件,比如login.properties、login_en_US.properties、login_zh_CN.properties等。
2. SpringBoot自动配置好了管理国际化资源文件的组件。

@EnableConfigurationProperties
public class MessageSourceAutoConfiguration {
   
    private static final Resource[] NO_RESOURCES = new Resource[0];

    public MessageSourceAutoConfiguration() {
   
    }

    @Bean
    @ConfigurationProperties(
        prefix = "spring.messages"
    )
    public MessageSourceProperties messageSourceProperties() {
   
        return new MessageSourceProperties();
    }

    @Bean
    public MessageSource messageSource(MessageSourceProperties properties) {
   
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        if (StringUtils.hasText(properties.getBasename())) {
   
            //设置国际化资源文件的基础名(去掉语言国家代码)
      
                messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
        }

        if (properties.getEncoding() != null) {
   
            messageSource.setDefaultEncoding(properties.getEncoding().name());
        }

        messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
        Duration cacheDuration = properties.getCacheDuration();
        if (cacheDuration != null) {
   
            messageSource.setCacheMillis(cacheDuration.toMillis());
        }

        messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
        messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
        return messageSource;
    }

原理
根据请求头带来的区域信息获取Locale进行国际化。

五、错误处理机制

1.默认的错误处理机制

  1. 浏览器,默认返回一个默认的错误页面。
  2. 其他客户端,默认响应一个json数据。

原理

  1. 在DefaultErrorAttributes中获取错误页面的信息
public class DefaultErrorAttributes implements ErrorAttributes {
   
 
    //获取错误页面的信息
    public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
   
        Map<String, Object> errorAttributes = new 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值