Spring Boot(一)Spring Boot核心技術(shù)

目錄
一兽泄、Spring Boot入門
? 1 Spring Boot簡介
? 2 微服務
? 3 入門案例
? 4 Spring Boot簡化部署
? 5 入門案例解析
? 6 使用Spring Initializer快速創(chuàng)建Spring Boot項目(以idea為例)
? 7 springboot內(nèi)嵌tomcat啟動方式和非內(nèi)嵌tomcat啟動方式
二啄踊、Spring Boot配置
? 1 簡介
? 2 yaml文件
? 3 配置文件注入
? 4 配置文件占位符
? 5 Profile
? 6 配置文件加載位置
? 7 外部配置加載順序
? \color{red}{8 自動配置原理}
三、日志
? 1 市面上的日志框架
? 2 SLF4j使用
? 3 SpringBoot日志關(guān)系
? 4 日志使用
? 5 切換日志框架
?
更多知識可參考:http://www.reibang.com/p/7dbaac902074


一装黑、Spring Boot入門

1 Spring Boot簡介
  • 簡化Spring應用開發(fā)的一個框架
  • 整個Spring技術(shù)棧的一個大整合
  • 將J2EE開發(fā)的一站式解決方案
2 微服務

Martin Fowler和James Lewis的《Microservices》是第一篇詳細介紹微服務的文章魔招。
Microservices全文
spring微服務官網(wǎng)

3 入門案例

在此之前,你需要掌握Spring框架和Maven的使用.

  • 創(chuàng)建maven項目,導入依賴
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  • 編寫主程序,啟動Spring Boot應用
/**
 * SpringBootApplication用來標注一個主程序,說明這是一個Spring Boot應用
 */
@SpringBootApplication
public class FirstSpringBootApplication {
    public static void main(String[] args) {
        //spring應用啟動
        SpringApplication.run(FirstSpringBootApplication.class, args);
    }
}
  • 編寫controller,service
@RestController
public class FirstController {
    @RequestMapping("/hello")
    public String hello(){
        return "hello world";
    }
}
4 Spring Boot簡化部署
  • 在pom.xml中導入插件,這個插件可以將應用打包成一個jar包
<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 打包過程
    在idea的右側(cè)欄找到maven,找到并點擊package.

    此時就會在控制臺輸出打包的信息

    在控制臺給出的路徑中找到生成的jar包,使用命令行運行命令java -jar springboot-1.0-SNAPSHOT.jar,運行成功會出現(xiàn)如下界面

    此時再訪問http://localhost:8080/hello,結(jié)果和在idea中運行結(jié)果一致,則部署成功.
5 入門案例解析
1) pom.xml文件
  • spring-boot-starter-parent,父項目是spring-boot-dependencies,它用來管理SpringBoot項目里的依賴版本
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
  </parent>

在以后的項目開發(fā)過程中,出現(xiàn)在spring-boot-dependencies的依賴就不需要寫版本號了

  • spring-boot-starter-web,是Spring Boot場景啟動器,它幫我們導入了web模塊正常運行所依賴的組件.
    Spring Boot將所有的功能場景都抽取出來,做成一個starter(啟動器),只需要在項目引入這些starter,相關(guān)場景的所有依賴都會導入進來
2) 主程序類

?? @SpringBootApplication,標注在某個類上,說明這個類是Spring Boot的主配置類,Spring Boot就應該運行在這個類的main()方法來啟動應用.我們進入這個注解可以看到

@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}
)}
)

??@SpringBootConfiguration,Spring Boot的配置類,標注在某個類上表示這是一個Spring Boot的配置類.而@SpringBootConfiguration注解上又標注了@Configuration,@Configuration表明某個類是一個配置類,配置類和配置文件有相同的作用,是容器中的一個組件(@Component)
?? @EnableAutoConfiguration,SpringBoot開啟自動配置功能.在這個注解上標注了@AutoConfigurationPackage,他是自動配置包,這個注解上又標注了@Import,它是Spring的底層注解.@AutoConfigurationPackage將主配置類(@SpringBootApplication標注的類)所在包及子包里面的的所有組件掃描到Spring容器;在@EnableAutoConfiguration上還標注了@Import({AutoConfigurationImportSelector.class}),它給容器導入組件AutoConfigurationImportSelector,而AutoConfigurationImportSelector是一個導入組件的選擇器,它將所有需要導入的組件以全類名的方式返回,最終會給容器倒入很多自動配置類(xxxAutoConfiguration),這些配置類會給容器導入這個場景所需要的所有組件,并配置好這些組件,它為我們免去了手動編寫配置文件和注入組件的工作.Spring Boot在啟動時從類路徑下的
META-INF/spring-autoconfigure-metadata.properties獲取指定的值,將這些值作為自動配置類導入到容器中,自動配置類就生效了.也就是說,J2EE的整體整合解決方案和自動配置都在spring-boot-autoconfigure-2.1.6.RELEASE.jar里`

6 使用Spring Initializer快速創(chuàng)建Spring Boot項目(以idea為例)
  • 新建Spring Initializer項目


  • 填寫包名和項目名


  • 需要什么功能,就加入相關(guān)的組件


  • finish



    系統(tǒng)生成了項目目錄和主程序


7 springboot內(nèi)嵌tomcat啟動方式和非內(nèi)嵌tomcat啟動方式

springboot內(nèi)嵌tomcat啟動方式和非內(nèi)嵌tomcat啟動方式可參考:
https://www.cnblogs.com/ysq2018China/p/10241201.html

二肌索、Spring Boot配置

1 簡介

1.Spring Boot使用一個全局的配置文件砂碉,配置文件名是固定的蛀蜜;

  • application.properties
  • application.yml

2.配置文件作用:修改Spring Boot自動配置的默認值

3.配置文件放在src/main/resources目錄或者類路徑/config下

2 yaml文件
1) YAML(YAML Ain't Markup Language),以數(shù)據(jù)為中心,比json、xml等更適合做配置文件
  • yaml配置示例
server:
  port: 8081
  • xml配置示例
<server>
  <port>8081</port>
</server>
2) YAML語法
* YAML基本語法

– k:(空格)v:表示一對鍵值對(空格必須有);
– 以空格的縮進來控制層級關(guān)系;只要是左對齊的一列數(shù)據(jù)剪个,都是同一個層級的
–縮進時不允許使用Tab鍵,只允許使用空格。
–縮進的空格數(shù)目不重要,只要相同層級的元素左側(cè)對齊即可
–大小寫敏感

* YAML 支持的三種數(shù)據(jù)結(jié)構(gòu)

– 對象:鍵值對的集合
– 數(shù)組:一組按次序排列的值
– 字面量:單個的霎奢、不可再分的值

* 對象、Map(屬性和值)(鍵值對):

k: v:在下一行來寫對象的屬性和值的關(guān)系饼灿;注意縮進;
對象還是k: v的寫法

friends:
        name: zhangsan
        age: 20

行內(nèi)寫法:

friends: {name: zhangsan,age: 18}
* 數(shù)組(List,Set):

用- 值表示數(shù)組中的一個元素

pets:
 - cat
 - dog
 - pig

行內(nèi)寫法

pets: [cat,dog,pig]
* 字面量:普通的值(數(shù)字幕侠,字符串,布爾)
  • k: v:字面直接來寫碍彭;
  • 字符串默認不用加上單引號或者雙引號晤硕;
  • "":雙引號悼潭;不會轉(zhuǎn)義字符串里面的特殊字符;特殊字符會作為本身想表示的意思
    name: "zhangsan \n lisi":輸出: zhangsan 換行 lisi
  • '':單引號窗骑;會轉(zhuǎn)義特殊字符女责,特殊字符最終只是一個普通的字符串數(shù)據(jù)
    name: ‘zhangsan \n lisi’:輸出漆枚;zhangsan \n lisi
3 配置文件注入
1) yaml方式

在之前創(chuàng)建的spring-boot-quick項目的基礎上加上如下代碼

  • application.yaml配置文件
person:
  name: zhangsan
  age: 18
  boss: false
  birth: 2017/12/12
  maps: {k1: v1,k2: 12}
  lists:
    - lisi
    - zhan
  dog:
    name: 小狗
    age: 2
  • Person對象
/**
 * @author:TiaNa
 * 配置文件中配置的每一個屬性的值,映射到這個組件中
 * 只有這個組件是日期中的組件,才能使用容器提供的功能
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private Integer age;
    private Boolean boss;
    private Date birthday;

    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;

    get/set方法...
}
  • pom.xml,導入配置文件處理器创译,以后編寫配置就有提示了
<!--導入配置文件處理器,配置文件進行綁定就會有提示-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
  • 重新運行SpringBootQuickApplication,編寫測試代碼
/**
 * springboot 單元測試
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootQuickApplicationTests {

    @Autowired
    Person person;

    @Test
    public void contextLoads() {
        System.out.println(person);
    }
}
  • 運行單元測試代碼后


2) properties方式

application.properties文件

# 配置person的值
person.name=李四
person.age=18
person.birthday=2018/7/17
person.boss=false
person.dog.name=10
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
3) @value獲取值

上面兩節(jié)墙基,不管是yaml方式還是properties方式注入软族,我們都使用的是@ConfigurationProperties注解獲取值,但其實@value注解也可以實現(xiàn)残制。

@Component
public class Person {
   /**
     * <bean class="Person">
     *      <property name="lastName" value="字面量/${key}從環(huán)境變量立砸、配置文件中獲取值/#{SpEL}"></property>
     * <bean/>
     */
    @Value("${person.last-name}")
    private String lastName;
    @Value("#{11*2}")
    private Integer age;
    @Value("true")
    private Boolean boss;

    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
4) @value和@ConfigurationProperties獲取值比較
序號 @value @ConfigurationProperties
功能 一個一個注入 批量注入配置文件的屬性
松散綁定(松散語法) 不支持 支持
SpEL(Spring表達式) 支持 不支持
JSP303數(shù)據(jù)校驗 不支持 支持
復雜類型封裝 不支持 支持
  • 松散綁定
    屬性名匹配規(guī)則(Relaxed binding)以下方式@ConfigurationProperties都能用firstName匹配
    – person.firstName:使用標準方式
    – person.first-name:大寫用-
    – person.first_name:大寫用_
    – PERSON_FIRST_NAME: 推薦系統(tǒng)屬性使用這種寫法
  • 配置文件注入值數(shù)據(jù)校驗(JSR303數(shù)據(jù)校驗)
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
   //lastName必須是郵箱格式
    @Email
    private String lastName;

如果說,我們只是在某個業(yè)務邏輯中需要獲取配置文件中的某個值初茶,使用@value颗祝;如果說,我們專門編寫了一個JavaBean來和配置文件進行映射恼布,需要使用@ConfigurationProperties螺戳。

5) @PropertySource、@ImportSource和@Bean
  • @PropertySource:加載指定的配置文件折汞;
/**
 * 將配置文件中配置的每一個屬性的值倔幼,映射到這個組件中
 * @ConfigurationProperties:告訴SpringBoot將本類中的所有屬性和配置文件中相關(guān)的配置進行綁定;
 *      prefix = "person":配置文件中哪個下面的所有屬性進行一一映射
 *
 * 只有這個組件是容器中的組件爽待,才能容器提供的@ConfigurationProperties功能损同;
 *  @ConfigurationProperties(prefix = "person")默認從全局配置文件中獲取值;
 *
 */
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
//@Validated
public class Person {

    /**
     * <bean class="Person">
     *      <property name="lastName" value="字面量/${key}從環(huán)境變量鸟款、配置文件中獲取值/#{SpEL}"></property>
     * <bean/>
     */

   //lastName必須是郵箱格式
   // @Email
    //@Value("${person.last-name}")
    private String lastName;
    //@Value("#{11*2}")
    private Integer age;
    //@Value("true")
    private Boolean boss;
  • @ImportResource:導入Spring的配置文件膏燃,讓配置文件里面的內(nèi)容生效;Spring Boot里面沒有Spring的配置文件何什,我們自己編寫的配置文件组哩,也不能自動識別;@ImportResource標注在一個配置類上使Spring的配置文件生效富俄,加載進來禁炒;
@ImportResource(locations = {"classpath:beans.xml"})
  • @Bean
/**
 * @Configuration:指明當前類是一個配置類;就是來替代之前的Spring配置文件
 * 在配置文件中用<bean><bean/>標簽添加組件
 */
@Configuration
public class MyAppConfig {

    //將方法的返回值添加到容器中霍比;容器中這個組件默認的id就是方法名
    @Bean
    public HelloService helloService02(){
        System.out.println("配置類@Bean給容器中添加組件了...");
        return new HelloService();
    }
}

SpringBoot推薦給容器中添加組件的方式:推薦使用全注解的方式
1幕袱、配置類@Configuration(相當于Spring配置文件)
2、使用@Bean給容器中添加組件

4 配置文件占位符
1) 隨機數(shù)
${random.value}悠瞬、${random.int}们豌、${random.long}
${random.int(10)}涯捻、${random.int[1024,65536]}
2) 占位符獲取之前配置的值,如果沒有可以是用:指定默認值
person.last-name=張三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15
5 Profile
1)多Profile文件

我們在主配置文件編寫的時候望迎,文件名可以是application-{profile}.properties/yml障癌,默認使用application.properties的配置

2)yml支持多文檔塊方式
server:
  port: 8081
spring:
  profiles:
    active: prod

---
server:
  port: 8083
spring:
  profiles: dev


---

server:
  port: 8084
spring:
  profiles: prod  #指定屬于哪個環(huán)境
3)激活指定profile(三種方式)
  • 在配置文件中指定
spring.profiles.active=dev
  • 命令行辩尊,可以直接在測試的時候涛浙,配置傳入命令行參數(shù)
java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
  • 虛擬機參數(shù)
?   -Dspring.profiles.active=dev
6 配置文件加載位置

springboot 啟動會掃描以下位置的application.properties或者application.yml文件作為Spring boot的默認配置文件:

–file:./config/
–file:./
–classpath:/config/
–classpath:/

優(yōu)先級由高到底,高優(yōu)先級的配置會覆蓋低優(yōu)先級的配置摄欲;
SpringBoot會從這四個位置全部加載主配置文件轿亮;互補配置
我們還可以通過spring.config.location來改變默認的配置文件位置
項目打包好以后胸墙,我們可以使用命令行參數(shù)的形式我注,啟動項目的時候來指定配置文件的新位置;指定配置文件和默認加載的這些配置文件共同起作用形成互補配置迟隅;

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.properties
7 外部配置加載順序

Spring Boot 支持多種外部配置方式
這些方式優(yōu)先級參考官方文檔:https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-external-config
①命令行參數(shù)
所有的配置都可以在命令行上進行指定但骨,多個配置用空格分開; --配置項=值

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc

②來自java:comp/env的JNDI屬性
③Java系統(tǒng)屬性(System.getProperties())
④操作系統(tǒng)環(huán)境變量
⑤RandomValuePropertySource配置的random.屬性值
==
由jar包外向jar包內(nèi)進行尋找智袭;==
==
優(yōu)先加載帶profile==
⑥jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
⑦jar包內(nèi)部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
==
再來加載不帶profile*==
⑧jar包外部的application.properties或application.yml(不帶spring.profile)配置文件
⑨jar包內(nèi)部的application.properties或application.yml(不帶spring.profile)配置文件
⑩ @Configuration注解類上的@PropertySource
①①通過SpringApplication.setDefaultProperties指定的默認屬性

8 \color{red}{自動配置原理}(以SprinBoot2.1.8源碼為例)

配置文件能配置的屬性參照

1)SpringBoot啟動時加載主配置類奔缠,開啟了自動配置功能@EnableAutoConfiguration
2)@EnableAutoConfiguration作用:利用AutoConfigurationImportSelector給容器中導入組件,可以查看selectImports方法中的內(nèi)容:
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = 
this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
  • 這個方法用來獲取候選的配置
  • SpringFactoriesLoader.loadFactoryNames掃描所有jar包類路徑下META-INF/spring.factories补履,把掃描到的這些文件內(nèi)容包裝成Properties對象添坊,從properties中獲取到EnableAutoConfiguration.class類(類名)對應的值,然后把它們添加進容器中箫锤。
  • 最后將類路徑下META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到容器中贬蛙,
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
  • 每一個這樣的xxxAutoConfiguration都是容器中的組件,都加入到容器中谚攒,用它們做自動配置
3)每一個配置類進行自動配置(以HttpEncodingAutoConfiguration為例)
@Configuration      
@EnableConfigurationProperties({HttpProperties.class})    
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
    private final Encoding properties;
    public HttpEncodingAutoConfiguration(HttpProperties properties) {
        this.properties = properties.getEncoding();
    }
    @Bean
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
      filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
      filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
        return filter;
    }

  • @Configuration表示是一個配置類阳准,和以前編寫的配置文件一樣,可以給容器中加入組件馏臭;
  • @EnableConfigurationProperties 啟用指定類的ConfigurationProperties功能,將配置文件對應的值和HttpProperties綁定野蝇,并將HttpProperties加入到ioc容器中;
  • @ConditionalOnWebApplication括儒,spring底層@Conditional注解绕沈,如果滿足某個條件,整個配置類里的配置才能生效帮寻; @ConditionalOnWebApplication就是判斷當前應用是否是web應用乍狐,如果是則生效;
  • @ConditionalOnClass判斷當前有沒有CharacterEncodingFilter這個類,springmvc中解決亂碼的過濾器
  • @ConditionalOnProperty判斷是否存在spring.http.encoding.enabled;如果不存在固逗,判斷也是成立的浅蚪。即使配置文件中不配置默認也生效藕帜。
  • HttpEncodingAutoConfiguration只有一個有參構(gòu)造器的情況下,參數(shù)值就會從容器中拿惜傲;
  • @Bean給容器中添加組件洽故,這個組件的某些值需要從properties中獲取,而properties已經(jīng)和SpringBoot的配置文件映射了盗誊。

根據(jù)當前條件判斷配置類是否生效时甚,一旦生效,配置類就會給容器添加給中組件浊伙,這些組件的屬性是從對應的properties中獲取的撞秋,這些類里的屬性又是和配置文件綁定的

4) 所有配置文件中能配置的屬性xxxProperties類中封裝著长捧,配置文件能配置什么就可以參照某個功能對應的屬性類
//從配置文件spring.http中獲取指定的值和屬性進行綁定
@ConfigurationProperties( prefix = "spring.http")  
public class HttpProperties {
    private boolean logRequestDetails;
    private final HttpProperties.Encoding encoding = new HttpProperties.Encoding();
    public HttpProperties() {
    }

5) 用好自動配置類
  • SpringBoot啟動會加載大量的自動配置類
  • 看我們需要的功能是否已由SpringBoot自動配置類寫好嚣鄙,配置類中如果已經(jīng)寫好了組件,我們就不用配置了串结。
  • 給容器中自動配置類添加組件時哑子,會從properties獲取某些屬性,我們可以在配置文件中指定這些屬性的值肌割。
6) @Conditional注解(補充知識)

作用:必須是@Conditional指定的條件成立卧蜓,才給容器中添加組件,配置配里面的所有內(nèi)容才生效把敞;

@Conditional擴展注解 作用(判斷是否滿足當前指定條件)
@ConditionalOnJava 系統(tǒng)的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean弥奸;
@ConditionalOnMissingBean 容器中不存在指定Bean;
@ConditionalOnExpression 滿足SpEL表達式指定
@ConditionalOnClass 系統(tǒng)中有指定的類
@ConditionalOnMissingClass 系統(tǒng)中沒有指定的類
@ConditionalOnSingleCandidate 容器中只有一個指定的Bean奋早,或者這個Bean是首選Bean
@ConditionalOnProperty 系統(tǒng)中指定的屬性是否有指定的值
@ConditionalOnResource 類路徑下是否存在指定資源文件
@ConditionalOnWebApplication 當前是web環(huán)境
@ConditionalOnNotWebApplication 當前不是web環(huán)境
@ConditionalOnJndi JNDI存在指定項

自動配置類必須在一定的條件下才能生效盛霎;
那我們怎么知道哪些自動配置類生效?可以application.properties里通過debug=true屬性耽装,來讓控制臺打印自動配置報告愤炸。打印內(nèi)容如下:

=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:(自動配置類啟用的)
-----------------

   DispatcherServletAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
      - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
        
    
Negative matches:(沒有啟動,沒有匹配成功的自動配置類)
-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

   AopAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)

三掉奄、日志

1 市面上的日志框架

JUL规个、JCL、Jboss-logging姓建、logback诞仓、log4j、log4j2速兔、slf4j....

日志門面 (日志的抽象層) 日志實現(xiàn)
JCL(Jakarta Commons Logging) SLF4j(Simple Logging Facade for Java) jboss-logging Log4j JUL(java.util.logging) Log4j2 Logback

左邊選一個門面(抽象層)墅拭、右邊來選一個實現(xiàn);
SpringBoot選用 SLF4j和logback

2 SLF4j使用
1)如何在系統(tǒng)中使用SLF4j

官網(wǎng): https://www.slf4j.org
以后開發(fā)的時候憨栽,日志記錄方法的調(diào)用帜矾,不應該來直接調(diào)用日志的實現(xiàn)類翼虫,而是調(diào)用日志抽象層里面的方法;
給系統(tǒng)里面導入slf4j的jar和 logback的實現(xiàn)jar

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
 public static void main(String[] args) {
 Logger logger = LoggerFactory.getLogger(HelloWorld.class);
 logger.info("Hello World");
 }
}

系統(tǒng)中使用slf4j的方法:可參考https://www.slf4j.org/manual.html


每一個日志的實現(xiàn)框架都有自己的配置文件屡萤。使用slf4j以后珍剑,配置文件還是做成日志實現(xiàn)框架自己本身的配置文件;

2)遺留問題

A(slf4j+logback): Spring(commons-logging)死陆、Hibernate(jboss-logging)招拙、MyBatis、xxxx
如上措译,A系統(tǒng)使用了許多框架别凤,且每個框架日志輸出使用的方式都不同,如何統(tǒng)一日志記錄领虹,所有框架統(tǒng)一使用slf4j進行輸出规哪?
解決辦法:


如何讓系統(tǒng)中所有的日志都統(tǒng)一到slf4j;
1塌衰、將系統(tǒng)中其他日志框架先排除出去诉稍;
2、用中間包來替換原有的日志框架最疆;
3杯巨、我們導入slf4j其他的實現(xiàn)

3 SpringBoot日志關(guān)系
  • SpringBoot使用它來做日志功能:
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
 </dependency>
  • 底層依賴關(guān)系:

    總結(jié):
    ? 1)SpringBoot底層也是使用slf4j+logback的方式進行日志記錄
    ? 2)SpringBoot也把其他的日志都替換成了slf4j;
    ==SpringBoot能自動適配所有的日志努酸,而且底層使用slf4j+logback的方式記錄日志服爷,引入其他框架的時候,只需要把這個框架依賴的日志框架排除掉即可获诈;==
    比如在SpringBoot1.x版本中引入spring時就做了這樣的處理
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
       </exclusions>
</dependency>
2 日志使用
1)默認配置

SpringBoot默認幫我們配置好了日志仍源;

  • 日志級別
    //記錄器
    Logger logger = LoggerFactory.getLogger(getClass());
    @Test
    public void contextLoads() {
        //System.out.println();
        //日志的級別;
        //由低到高   trace<debug<info<warn<error
        //可以調(diào)整輸出的日志級別烙荷;日志就只會在這個級別以以后的高級別生效
        logger.trace("這是trace日志...");
        logger.debug("這是debug日志...");
        //SpringBoot默認給我們使用的是info級別的镜会,沒有指定級別的就用SpringBoot默認規(guī)定的級別;root級別
        logger.info("這是info日志...");
        logger.warn("這是warn日志...");
        logger.error("這是error日志...");
    }
  • 日志輸出格式
    日志輸出格式:
        %d表示日期時間终抽,
        %thread表示線程名戳表,
        %-5level:級別從左顯示5個字符寬度
        %logger{50} 表示logger名字最長50個字符,否則按照句點分割昼伴。 
        %msg:日志消息匾旭,
        %n是換行符
    -->
    %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
  • SpringBoot修改日志的默認配置
logging.level.com.logging=trace

#logging.path=
# 不指定路徑在當前項目下生成springboot.log日志

# 可以指定完整的路徑;
#logging.file=G:/springboot.log

# 在當前磁盤的根路徑下創(chuàng)建spring文件夾和里面的log文件夾圃郊;使用 spring.log 作為默認文件
logging.path=/spring/log

#  在控制臺輸出的日志的格式
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n

# 指定文件中日志輸出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
logging.file logging.path Example Description
(none) (none) 只在控制臺輸出
指定文件名 (none) my.log 輸出日志到my.log文件
(none) 指定目錄 /var/log 輸出到指定目錄的 spring.log 文件中
2)指定配置

給類路徑下放上每個日志框架自己的配置文件即可价涝;SpringBoot就不使用他默認配置的了

Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

logback.xml:直接就被日志框架識別了;

logback-spring.xml:日志框架不直接加載日志的配置項持舆,由SpringBoot解析日志配置色瘩,可以使用SpringBoot的高級Profile功能

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
    可以指定某段配置只在某個環(huán)境下生效
</springProfile>

如:

<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--
        日志輸出格式:
            %d表示日期時間伪窖,
            %thread表示線程名,
            %-5level:級別從左顯示5個字符寬度
            %logger{50} 表示logger名字最長50個字符居兆,否則按照句點分割覆山。 
            %msg:日志消息,
            %n是換行符
        -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <springProfile name="dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
            <springProfile name="!dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
        </layout>
    </appender>

如果使用logback.xml作為日志配置文件泥栖,還要使用profile功能簇宽,會有以下錯誤
no applicable action for [springProfile]

5 切換日志框架

可以按照slf4j的日志適配圖,進行相關(guān)的切換吧享;
slf4j+log4j的方式:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <artifactId>logback-classic</artifactId>
      <groupId>ch.qos.logback</groupId>
    </exclusion>
    <exclusion>
      <artifactId>log4j-to-slf4j</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
</dependency>

切換為log4j2

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末魏割,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子钢颂,更是在濱河造成了極大的恐慌钞它,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甸陌,死亡現(xiàn)場離奇詭異须揣,居然都是意外死亡,警方通過查閱死者的電腦和手機钱豁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疯汁,“玉大人牲尺,你說我怎么就攤上這事』衔茫” “怎么了谤碳?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長溢豆。 經(jīng)常有香客問我蜒简,道長,這世上最難降的妖魔是什么漩仙? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任搓茬,我火速辦了婚禮,結(jié)果婚禮上队他,老公的妹妹穿的比我還像新娘卷仑。我一直安慰自己,他們只是感情好麸折,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布锡凝。 她就那樣靜靜地躺著,像睡著了一般垢啼。 火紅的嫁衣襯著肌膚如雪窜锯。 梳的紋絲不亂的頭發(fā)上张肾,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天,我揣著相機與錄音锚扎,去河邊找鬼捌浩。 笑死,一個胖子當著我的面吹牛工秩,可吹牛的內(nèi)容都是我干的尸饺。 我是一名探鬼主播,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼助币,長吁一口氣:“原來是場噩夢啊……” “哼浪听!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起眉菱,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤迹栓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俭缓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體克伊,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年华坦,在試婚紗的時候發(fā)現(xiàn)自己被綠了愿吹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡惜姐,死狀恐怖犁跪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情歹袁,我是刑警寧澤坷衍,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站条舔,受9級特大地震影響枫耳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜孟抗,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一迁杨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夸浅,春花似錦仑最、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春预皇,著一層夾襖步出監(jiān)牢的瞬間侈玄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工吟温, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留序仙,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓鲁豪,卻偏偏與公主長得像潘悼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350