java——springboot(1)

springboot需要一个主程序类,通过@SpringBootApplication来标注,例:

@SpringBootApplication
public class LzjSts2Application {

    public static void main(String[] args) {
        SpringApplication.run(LzjSts2Application.class, args);
    }

}

这里的这个标注@SpringBootApplication所起到的作用我们可以看代码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

@SpringBootConfiguration:表示这是springboot的一个配置类;

而之所以spring-boot几乎不用写什么配置文件就在于@EnableAutoConfiguration这个标注类;里面是:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

这里的@AutoConfigurationPackage会使得容器扫描主程序类所在包以下的所有子包,相当于之前做配置时的扫描功能;而AutoConfigurationImportSelector.class这个是自动导入配置的选择器;里面定义了一个selectImports()方法将要导入的组件类名以String[]的形式返回。这些组件就会被添加到容器中;同时也会导入这些组件所对应的自动配置类:(xxxAutoConfiguration);而这些自动配置类其实是存在于依赖的jar包里:

 

 至此,springboot就仅仅通过一个@SpringBootApplication标注就把我们之前需要大量配置的步骤都给省略了;

pom.xml解析:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
</parent>

这个父项目里面还有个父项目spring-boot-dependencies,这里面就定义好了各种导入依赖的版本,Spring Boot的版本仲裁中心;

spring-boot-starter:spring boot场景启动器,帮我们导入 了各种模块正常运行时所依赖的组件;

 

spring-boot的资源目录:

 

 默认的全局配置文件名是固定的:

application.properties和application.yml;

主要来说下yml格式的配置文件,这是以数据为中心的文件,因为里面省略的大量的标签及无实际意义的标注符号,其基本的语法:k:(空格)v,通过左缩进来表示子级关系,同一列的左缩进其层级相同,列表里的元素通过-(空格)v来表示,也可以通过[]中括号、里面用,逗号隔开来表示;大小写敏感;---三短横杆可以在一个文档分成多文档;

获取全局配置文件的数据:

可以通过@ConfigurationProperties(prefix = "xxx"),这个xxx是表示在yml文件中具体对应的元素;

@ConfigurationProperties就是告诉springboot将本类中所有的属性和配置文件相关的配置进行绑定;而如果要想@ConfigurationProperties起作用,那它所标记的类一定得是容器的组件,也就是说它得被@Component标注;

在做配置文件时可以导入spring-boot-configuration-procrssor这个文件处理器依赖,这样在文件进行绑定时就会有提示;

可以通过@Value来传值:

如:

 

 

 

 

 所谓的松散绑定就是用“_”或“-”后接小写字母都表示是大写字母,即:

firstName == first-name

数据校验指的是可以限定变量是哪种类型的,如

 

 如果lastName通过配置文件所注入的值不是邮箱的格式,那么就会报错;

复杂类型封装是指如Map、对象封装之类的数据类型,Value并不能直接表示一个对象‘;

-------------------------------------------------------------------------------------------------------------------------------

 

突然想做个备注:@RestController注解相当于@ResponseBody + @Controller合在一起的作用。

 

-------------------------------------------------------------------------------------------------------------------------------

 

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

@ImportResource:导入Spring的配置文件,让配置文件生效,因此这个标准是标注在一个配置类里的,如主配置类中:

 

 

 但是这种导入并不值得提倡,常用的还是编写配置类,如:

@Configuration //指明配置类
public class MyAppConfig{
     @Bean//将方法的返回值加入组件中,且其名字即是方法名
      public HelloService helloService(){
           return
      }
}

上述这种添加配置文件的方法才是Spring提倡的,这和springmvc其实是一致的。

 

springboot里可以使用${app.name}来指定某个值,如果找不到该值想使用默认值的话只需通过冒号后引入即可,如${app.name:默认值}

 

Profile多环境支持:如

默认的配置文件是application.properties;

当我们想在不同环境运行时,如在开发环境中使用开发配置文件,生产环境中使用生产配置文件,这个时候我们可以同过编写配置文件application-{profile}.properties,如:application-dev.properties或application-prod.properties;然后激活对应的profile即可,激活的方式有以下几种:

1、在默认配置文件中激活指定的profile,如spring.profiles.active=dev;加上这个生命后,程序运行所使用的就是application-dev.properties这个配置文件了;

2、在启动时命令行中指定--spring.profiles.active=dev激活;这里包括直接测试时在命令行加入,也可在打包后运行jar文件时加入,都能起到效果

3、虚拟机激活,在虚拟机运行参数中加入参数-Dspring.profiles.active=dev;

 

SpringBoot配置文件的加载路径:

 

 

 所有配置都会被加载,即会形成一种互补机制;

 

外部配置的加载顺序:

 

 

 

 自动配置原理:

 

 

 以一个例子来说明如何实现自动配置:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ServerProperties.class)//启用指定类的ConfigurationProperties功能;
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)//判断当前应用是不是web应用,如果是这个配置类才会生效
@ConditionalOnClass(CharacterEncodingFilter.class)//判断当前项目有没有这个类
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)//判断配置文件是否有server.servlet.encoding=true;如果没有,其实也是默认true的;
public class HttpEncodingAutoConfiguration {

点进去ServerProperties这个类中,截取部分内容如下:

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

    /**
     * Server HTTP port.
     */
    private Integer port;

    /**
     * Network address to which the server should bind.
     */
    private InetAddress address;

    @NestedConfigurationProperty
    private final ErrorProperties error = new ErrorProperties();

    /**
     * Strategy for handling X-Forwarded-* headers.
     */
    private ForwardHeadersStrategy forwardHeadersStrategy;

这里就表明了我们配置文件能配置哪些信息了,如:server.port、server.address、server.forwardHeadersStrategy等等;

也就是这个类前面的种种标准都是用来判断这个配置类是否生效?如果生效,下面的代码:

@Bean
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
        return filter;
    }

即为容器加入一个CharacterEncodingFilter组件,而该组件所用的值this.properties.getCharset().name()就是根据

  @EnableConfigurationProperties(ServerProperties.class)//启用指定类的ConfigurationProperties功能;

这个指定类所对应的properties配置了;

对于自动配置类是否加载组件进容器,是需要在一定条件下才能生效的,大部分会通过@Conditional来判断是否生效;而怎么才能知道哪些配置类有用哪些没用呢?

可以在配置文件里配置debug=true属性,来让控制台打印自动配置报告,这样就可以很方便知道哪些自动配置类生效;

这里的自动配置类原理比较重要,也算是以后熟络Spring-Boot的必经之路,做下总结:

 

posted @ 2020-06-03 17:46  xiao兆  阅读(182)  评论(0编辑  收藏  举报