主頁 > 軟體設計 > Spring Boot入門

Spring Boot入門

2021-02-16 14:09:32 軟體設計

目錄

一、了解

1、簡介

2、微服務

二、Helloword

1、創建Maven專案

2、匯入Spring Boot相關依賴

3、配置Spring Boot應用

4、撰寫Controller

5、啟動應用

6、簡化部署

7、分析

8、快速創建SpringBoot應用

三、SpringBoot的配置

1、yml的基本語法

2、值的寫法

3、.yml組態檔值的獲取@ConfigurationProperties

4、properties組態檔編碼的問題

5、@ConfigurationProperties和@Value的區別

6、@PropertySource和@ImportResource

7、組態檔的占位符

8、Profile

(1)多profile檔案形式

(2)yml支持多檔案塊的方式

(3)命令列激活

9、組態檔的加載位置

10、自配置原理

SpringBoot精髓

11、配置@Conditional自動配置報告

四、SpringBoot與日志

1、日志框架

2、SLF4J的使用

3、遺留問題

4、SpringBoot中的日志使用

5、SpringBoot的默認配置

6、指定配置和Profile環境

五、SpringBoot與Web開發

1、靜態資源映射規則

2、模板引擎Thymeleaf

(1)引入

(2)使用

(3)語法規則

3、SpringMVC自動配置原理

4、擴展SpringMVC

5、全面接管SpringMVC

如何修改SpringBoot的默認配置

六、SpringBoot與Docker

1、Docker

2、核心概念:

3、使用步驟

4、安裝

5、Docker常用操作

(1)鏡像操作

(2)容器操作

七、SpringBoot與資料訪問

1、整合基本JDBC與資料源

2、JDBC-使用Druid資料源

3、整合Mybatis

注解版

注解聯合組態檔

八、SpringBoot啟動配置原理

事件監聽機制的測驗

九、自定義Starter


一、了解

1、簡介

Spring Boot來簡化Spring應用的開發,約定大于配置,去繁從簡,僅僅run就可以創建一個獨立的、產品級別的應用,

整個Spring技術堆疊的整和;

優點如下:

  • 快速創建可獨立運行的Spring專案以及主流框架集合
  • 使用嵌入式的Servlet容器,應用無需打成WAR包
  • starters(啟動器)自動依賴與版本控制
  • 大量的自動配置,簡化開發
  • 無需配置XML,無代碼生成,開箱即用
  • 準生成環境的運行時應用監控
  • 與云計算的天然集成

2、微服務

http://www.bdata-cap.com/newsinfo/1713874.html

2014 martinflower

微服務:架構風格

一個應用應該是一組小型服務,可以通過HTTP進行互通

每一個功能元素最終都是一個可獨立替換和獨立升級的軟體單元


二、Helloword

環境:

  • JDK1.7及以上
  • Maven3.3及以上
  • Spring Boot
  • IDEA、STS或者Eclipse

1、創建Maven專案

2、匯入Spring Boot相關依賴

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>
    </dependencies>

3、配置Spring Boot應用

HelloWordMainApplication.java

package com.springboot.rocke;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * ClassName:HelloWordMainApplication
 * Package:com.springboot.rocke
 * Description:
 *
 * @createDate:2021-02-10 14:28
 * @author:2655179348@qq.com
 */


/*
* @SpringBootApplication:來標注一個主程式類,表明這是一個SpringBoot應用
* */
@SpringBootApplication
public class HelloWordMainApplication {
    public static void main(String[] args) {

        //啟動Spring應用
        final ConfigurableApplicationContext run = SpringApplication.run(HelloWordMainApplication.class, args);
    }
}

4、撰寫Controller

package com.springboot.rocke;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * ClassName:HelloWordController
 * Package:com.springboot.rocke
 * Description:
 *
 * @createDate:2021-02-10 14:36
 * @author:2655179348@qq.com
 */
@Controller
public class HelloWordController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "hello word";
    }
}

5、啟動應用

啟動main方法即可

6、簡化部署

匯入插件:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

package打包后,直接使用java -jar命令即可運行

7、分析

(1)spring-boot-dependencies

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.4.RELEASE</version>
</parent>

父專案的父專案:真正管理SpringBoot的所有依賴版本;版本總裁:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.3.4.RELEASE</version>
</parent>

所以我們匯入默認依賴時不需要宣告版本的;

(2)spring-boot-starter-web

幫我們匯入了web模塊正常運行所依賴的組件

spring-boot-starter:SpringBoot場景啟動器

SpringBoot將所有的功能場景都抽取出來了,做成一個個starters,我們只需要在專案中引入這些starters,相關場景的所以依賴,都會匯入進來,要用什么功能,就匯入對應的啟動器

(3)主程式類,主入口類

@SpringBootApplication標注一個主程式類,表明這是一個SpringBoot的主配置類,SpringBoot會運行這個類的main方法來啟動SpringBoot應用

@SpringBootConfiguration標識這是個Springboot的配置類

@EnableAutoConfiguration:開啟自動配置功能:-》

@EnableAutoConfiguration

@AutoConfigurationPackage:自動配置包-》

@AutoConfigurationPackage

@Import(AutoConfigurationPackages.Registrar.class)

@Import:Spring的底層注解,給容器中匯入組件,匯入的組件由AutoConfigurationPackages.Registrar.class這個類來指定;

AutoConfigurationPackages.Registrar.class:將主配置類(@SpringBootApplication所標注的類)所在的包以及下面所有的子包得到所有組件掃描到Spring容器中;

@Import(AutoConfigurationImportSelector.class):匯入哪些組件的選擇器

將所有需要匯入的組件,以全類名的方式回傳;這些組件就會被添加到容器中;最侄訓給容器中匯入非常多的自動配置類:給容器中匯入這個場景需要的所有組件并配置好這些組件,

有了自動配置類,就免去了我們收到撰寫配置和注入組件的作業;

Spring Boot在啟動時,從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值,作為指定配置類,匯入到容器中,自動配置類就生效了,幫我們進行自動配置,

J2EE的整體的整合解決方案和自動裝配都在spring-boot-autoconfigure這個包下


8、快速創建SpringBoot應用

使用Spring Initializer快速創建SpringBoot專案

快速生成的SpringBoot專案:

  1. 主程式已經生成好了,我們只需要撰寫我們自己的邏輯
  2. 組態檔夾(resource)的結構:
  • static=》靜態資源(css,js),

  • templates=》所有的模板頁面(嵌入式的tomcat不支持jsp,但我們可以使用模板引擎,比如freemarker、thymeleaf)

  • application.properties:SpringBoot應用的組態檔,,可以修改一些默認配置


三、SpringBoot的配置

SpringBoot使用一個全域組態檔,組態檔名是固定的

  • application.properties
  • application.yml

組態檔的作業:修改SpringBoot自動配置的默認值

.yml是YAML(YAML Ain`t Markup Language)語言的檔案,以資料為中心,比JSON、XML等更適合做組態檔,

同一目錄下,properties優先級高于yml

1、yml的基本語法

key:(空格,必須要有)value

表示一組鍵值對,

如果屬性有層級關系,以空格的縮進來控制層級關系,只要是左對齊的一列資料,都是同一個層級的,

2、值的寫法

字面量:數字,字串,布林值

k: v 字面量直接寫就好了

字串默認不用加上單引號或者雙引號

“”:雙引號引起的字串,不會轉義里邊的特殊字符,特殊字符會作為本身要表示的意思

‘’:單引號引起的字串,會轉義特殊字符,特殊字符最終只是一個普通字串資料

物件

k: v 物件還是鍵值對的方式,在下一行來寫物件的屬性和值的對應關系,注意縮進

也可以這樣寫:

k: {xx:xx,xxx:xxx}

陣列

用-(空格)值表示陣列中的一個元素

也可以這么來寫:

3、.yml組態檔值的獲取@ConfigurationProperties

安裝依賴:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

結果:

4、properties組態檔編碼的問題

5、@ConfigurationProperties和@Value的區別

@Value

    /*
    * <bean>
        <property name="" value="字面量/${}從環境變數、組態檔中取值/#{SpEL}"></property>
      </bean>
    * */

    @Value("${person.lastName}")
    private String lastName;
    @Value("#{11*2}")
    private Integer age;
    @Value("true")
    private Boolean man;

@ConfigurationProperties@Value
功能批量注入組態檔的屬性,只需要制定prefix一個一個指定
松散系結name支持駝峰與-、_的轉化不支持
SpEL不支持支持
JSR303資料校驗支持,@Validated不支持

JSR303校驗:

@Component
@Validated
@ConfigurationProperties(prefix = "person")
public class Person {



    @Email
    private String lastName;

如果我們只是在某個業務邏輯中需要獲取一下組態檔中的某項值,我們就使用@Value,

如果是我們專門撰寫了1一個javaBean來和組態檔進行映射,我們就直接使用@ConfigurationProperties

6、@PropertySource和@ImportResource

@PropertySource:加載指定的組態檔

@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = "classpath:person.properties")
public class Person {

@ImportResource:匯入Spring的組態檔,@ImportResource標注在配置類上,讓組態檔中的內容生效

SpringBoot推薦給容器中添加組件的方式:全注解的方式

/*@Configuration:指明當前類是一個配置類
* */
@Configuration
public class MyAppConfig {

    //@Bean將方法的回傳值添加到容器中,這個組件的默認id就是方法名
    @Bean
    public HelloService helloService(){
        return new HelloService();
    }
}

7、組態檔的占位符

8、Profile

Profile是Spring對不同環境提供不同配置功能的支持,可以通過激活、指定引數等方式快速切換環境,

(1)多profile檔案形式

在主組態檔撰寫的時候,檔案名可以是application-{profile}.properties/yml

多個主組態檔,默認使用appl.properties的配置

在主組態檔中指定要激活的配置

(2)yml支持多檔案塊的方式

server:
  port: 8080
spring:
  profiles:
    active: dev


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



---
server:
  port: 8084

spring:
  profiles: prod

(3)命令列激活

命令列

--spring.profiles.active=dev

9、組態檔的加載位置

springboot啟動會默認掃描一下位置的application.properties或者.yml作為默認配置

  • file:./config/
  • file: ./
  • classpath:/config/
  • classpath:/

以上優先級是從高到低所有位置的檔案都會被加載,高優先級配置的內容會覆寫低優先級配置的內容

我們可以通過spring.config.location來改變默認組態檔的位置:專案打包后,我們可以使用命令列引數的形式來指定組態檔的新位置;指定的新組態檔和默認加載的組態檔會同時起作用,形成互補配置

10、自配置原理

(1)SpringBoot啟動的時候,加載主配置類,開啟了自動配置功能(@EnableAutoConfiguration)

(2)@EnableAutoConfiguration的作用

利用AutoConfigurationImportSelector給容器中匯入組件

可以查看selectImports方法的內容

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());

SpringFactoriesLoader.loadFactoryNames()掃描所有的jar包下的META-INF/spring.factories,把掃描到的這些檔案的內容包裝成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.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
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.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
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.Neo4jReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
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.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
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.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
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.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
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.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
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(http編碼自動配置)為例:

根據當前的不同條件判斷,決定這個配置類是否生效

所有在組態檔中能配置的屬性都是在XXXProperties類中封裝著,組態檔能配置什么,就可以參照某個功能對應的這個屬性類

根據當前的不同條件判斷,決定這個配置類是否生效,一旦生效,這個配置類就會給容器中添加各種組件,這些組件的屬性是從對應的properties中獲取的,這些類里邊的每一個屬性又是和組態檔系結的,


SpringBoot精髓

(1)SpringBoot啟動會加載大量的自動配置類

(2)我們看我們需要的功能有沒有SpringBoot寫好的自動配置類;

(3)我們再來看,這個自動配置類中到底配置了哪些組件(只要我們要用的組件,我們就不需要再來配置了,如果沒有,就需要我們自己寫一個配置注入)

(4)給容器中的自動配置類添加組件的時候,會從properties類中獲取某些屬性,我們就可以在組態檔中指定這些屬性的值

xxxAutoConfiguration:指定配置類:給容器中添加組件

xxxProperties:封裝組態檔中的相關屬性


11、配置@Conditional自動配置報告

自動配置類在一定的條件下才能生效

我們怎么知道哪些自動配置類生效了?

我們可以配置debuh=true,開啟springboot的debug模式,可以很方便的知道哪些配置類生效了

自動配置配啟用了的

未啟用的自動配置類


四、SpringBoot與日志

1、日志框架

日志門面(日志的抽象層)日志實作

JCL(Jakarta Commons Logging)

SLF4j(Simple Logging Facade for java)

jboss-logging

Log4j

JUC(java.utils.logging)

Log4j2

Logback

日志門面選slf4j,日志實作選擇logback

SpringBoot:底層是Spring,Spring默認使用的是JCL,SprngBoot選用的是SLF4J和Logback

2、SLF4J的使用

官方檔案:http://www.slf4j.org/manual.html

日志記錄方法的呼叫,應該呼叫日志抽象層的方法,而不是日志的實作類

每一個日志的實作框架都有自己的組態檔,使用slf4j后,組態檔還是做成日志實作框架的組態檔,

3、遺留問題

不同框架使用不同的默認日志框架實作,

所以我們需要統一日志記錄,即使別的框架,我們也要統一使用slf4j和logback進行日志輸出,

(1)系統中先將其他的日志框架都排除出去,

(2)用中間包來替換原有的日志框架(貍貓換太子包)

(3)匯入slf4j其他的實作

4、SpringBoot中的日志使用

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.4.2</version>
      <scope>compile</scope>
    </dependency>

SpringBoot使用它來做日志功能

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
      <version>2.4.2</version>
      <scope>compile</scope>
    </dependency>

(1)SpringBoot底層也是使用slf4j加logback的方式進行日志記錄;

(2)SpringBoot也把其他的日志替換成了slf4j;

(3)如果我們引入其他組件,一定要把引入的框架的日志依賴移除掉;

5、SpringBoot的默認配置

默認已經幫我們配置好日志了,我們直接使用就可以了

package com.springbootlogin.demomain;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemomainApplicationTests {
    final Logger logger = LoggerFactory.getLogger(getClass());

    @Test
    void contextLoads() {

        //日志的級別:由低到高:trace-debug-info-warn-error
        //我們可以調整日志的輸出級別,日志就只會在這個級別以及以后的高級別生效
        //springboot默認給我們使用的是info級別的日志
        //沒有指定級別的,就用SpringBoot默認規定的級別
        logger.trace("這是trace日志");
        logger.debug("這是debug日志");
        logger.info("這是info日志");
        logger.warn("這是warn日志");
        logger.error("這是error日志");

    }
}

全域配置:

#調整日志級別
logging.level.com.springbootlogin=trace
#logging.file.name和logging.file.path都不指定的情況下,日志只在控制臺輸出
#只指定logging.file.name檔案名,那就把日志輸出到當前專案下的指定的檔案
logging.file.name=springlogging.log
#也可以指定生成日志的目錄,name和path是互斥的
logging.file.path=./spring/log
#在控制臺輸出的日志的格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS}[%thread] %5level %logger{50} -%msg%n
#指定檔案中日志輸出的格式
logging.pattern.file=%d{yyyy-MM-dd}===[%thread] === %-5level === %logger{50} ==== -%msg%n

6、指定配置和Profile環境

給類路徑下放上每個日志框架自己的組態檔即可,SpringBoot就不會使用自己的默認配置

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

我們推薦使用logback-spring.xml,日志框架識別不了,這個時候由SpringBoot加載,可以使用SpringProfile功能:指定某段配置只在某個環境下生效,

五、SpringBoot與Web開發

使用SpringBoot:

1、創建SpringBoot應用

2、SpringBoot已經默認將這些場景配置好了,只需要在組態檔中指定少量配置,幾月可以運行起來了

3、撰寫業務代碼

自動配置原理:

xxxAutoConfiguration:幫我們給容器中自動組態檔

xxxProperties:配置類,來封裝組態檔的內容

1、靜態資源映射規則

        @Override
		protected void addResourceHandlers(ResourceHandlerRegistry registry) {
			super.addResourceHandlers(registry);
			if (!this.resourceProperties.isAddMappings()) {
				logger.debug("Default resource handling disabled");
				return;
			}
			ServletContext servletContext = getServletContext();
			addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
			addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
				registration.addResourceLocations(this.resourceProperties.getStaticLocations());
				if (servletContext != null) {
					registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
				}
			});
		}

		private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
			addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
		}

		private void addResourceHandler(ResourceHandlerRegistry registry, String pattern,
				Consumer<ResourceHandlerRegistration> customizer) {
			if (registry.hasMappingForPattern(pattern)) {
				return;
			}
			ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
			customizer.accept(registration);
			registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
			registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
			customizeResourceHandlerRegistration(registration);
		}

(1)所有“/webjars/**”,都去classpath:/META-INF/resources/webjars/找資源;

  • webjars:以jar包的方式引入靜態資源;https://www.webjars.org

在訪問時,只需要寫webjars下邊資源的名稱;

(2)“/**”會去以下路徑查找:

"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"

(3)歡迎頁:靜態資源檔案夾下的所有index.html頁面

		@Bean
		public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
				FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
			WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
					new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
					this.mvcProperties.getStaticPathPattern());
			welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
			welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
			return welcomePageHandlerMapping;
		}

(4)favicon.ioc:所有的**/favicon.ico都是在靜態資源檔案夾下找

(5)自定義靜態資源路徑,會取消默認配置(默認配置就不生效了)

2、模板引擎Thymeleaf

SpringBoot推薦Thymeleaf:語法簡單,功能強大;

(1)引入

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

(2)使用

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

	private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;

	public static final String DEFAULT_PREFIX = "classpath:/templates/";

	public static final String DEFAULT_SUFFIX = ".html";

只要我們把HEML頁面放在classpath:/templates/下,thymeleaf就會自動渲染;

    @RequestMapping("/success")
    public String success() {
        //classpath:/templates/success.html
        return "success";
    }

使用:

  1. 匯入thymeleaf的名稱空間:
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>success</title>
</head>
<body>
<h2>我是success頁面</h2>
<div>
    <!--th:text:將div里的文本內容設定為指定的值-->
    <div th:text="${hello}">這里顯示歡迎資訊</div>
</div>
</body>
</html>

(3)語法規則

具體參考:https://www.cnblogs.com/itdragon/archive/2018/04/13/8724291.html

3、SpringMVC自動配置原理

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc

Spring MVC自動配置

Spring Boot為Spring MVC提供了自動配置,可與大多數應用程式完美配合,

自動配置在Spring的默認值之上添加了以下功能:

  • 包含ContentNegotiatingViewResolverBeanNameViewResolver

  • 支持提供靜態資源,包括對WebJars的支持,

  • 自動注冊ConverterGenericConverterFormatter豆類,

  • 支持HttpMessageConverters

  • 自動注冊MessageCodesResolver

  • 靜態index.html支持,靜態首頁訪問

  • 自動使用ConfigurableWebBindingInitializer

如果要保留這些Spring Boot MVC定制并進行更多的MVC定制(攔截器,格式化程式,視圖控制器和其他功能),則可以添加自己@Configuration的type類,WebMvcConfigurer不添加 @EnableWebMvc

如果你想提供的定制情況RequestMappingHandlerMappingRequestMappingHandlerAdapter或者ExceptionHandlerExceptionResolver,仍然保持彈簧引導MVC自定義,你可以宣告型別的豆WebMvcRegistrations,并用它來提供這些組件的定制實體,

如果你想利用Spring MVC中的完全控制,你可以添加自己的@Configuration注解為@EnableWebMvc,或者添加自己的@Configuration-annotatedDelegatingWebMvcConfiguration中的Javadoc中所述@EnableWebMvc

ContentNegotiatingViewResolver:

  • 自動配置了ViewResolver()視圖決議器:根據方法的回傳值,獲取視圖物件(View),視圖物件決定如何渲染(轉發、重定向)

  • ContentNegotiatingViewResolver:組合所有的視圖決議器的;

  • 我們可以自己個容器中添加一個視圖決議器,ContentNegotiatingViewResolver自動的將其組合進來;

Converter:轉換器,型別轉換使用Converter組件;

Formatter:格式化器,日期轉化等;

		@Bean
		@Override
		public FormattingConversionService mvcConversionService() {
			Format format = this.mvcProperties.getFormat();
			WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()
					.dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
			addFormatters(conversionService);
			return conversionService;
		}

我們自己添加的格式化器,只需要放在容器中即可;

HttpMessageConverters:Springmvc用來轉換http請求和回應的,POJO-》Json

private final ObjectProvider<HttpMessageConverters> messageConvertersProvider;

從容器中獲取所有的HttpMessageConverters,我們要自定義,也是直接添加到容器中即可

MessageCodesResolver:定義錯誤代碼生成規則的;

ConfigurableWebBindingInitializer:初始化WebDataBinder(請求資料系結到JavaBean中)

@Override
		protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer(
				FormattingConversionService mvcConversionService, Validator mvcValidator) {
			try {
				return this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
			}
			catch (NoSuchBeanDefinitionException ex) {
				return super.getConfigurableWebBindingInitializer(mvcConversionService, mvcValidator);
			}
		}

4、擴展SpringMVC

    <mvc:view-controller path="/hello" view-name="success"/>
    
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/hello"/>
            <bean></bean>
        </mvc:interceptor>
    </mvc:interceptors>

撰寫一個配置類(@Configuration),是WebMVCConfigurationAdapter型別(現在是實作WebMvcConfigurer這個介面),不能標注@EnableWebMvc注解

* 使用WebMvcConfigurer擴展SpringMvc功能*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //瀏覽器發送rocke請求,也是來到success頁面
        registry.addViewController("/rocke").setViewName("success");
    }
}

既保留了所有的自動配置,也能使用我們擴展配置

原理:

(1)WebMvcAutoConfiguration是SpringMvc的自動配置類

(2)在做其他配置時,會匯入@Import(EnableWebMvcConfiguration.class)

@Configuration(proxyBeanMethods = false)
	@EnableConfigurationProperties(WebProperties.class)
	public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {





    //從容器中獲取所有的WebMvcConfigurers
	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}

(3)容器中所有的WebMvcConfigurer都會一起起作用

(4)我們的配置類也會起作用

效果:SpringMvc自動配置和我們自己的配置都會起作用

5、全面接管SpringMVC

SpringBoot對SpringMvc的自動配置我們不需要了,所有的都是我們自己配;

只需要在配置類中添加@EnableWebMvc,所有的SpringMvc的自動配置都失效了;

原理:

@EnableWebMvc將WebMvcConfigurationSupport組件匯入進來;

匯入的WebMvcConfigurationSupport只是SpringMvc的最基本的功能;

...............................................................

...........以后熟練使用再回來啃原始碼吧,今天先跳過,腦子嗡嗡的

如何修改SpringBoot的默認配置

模式:

(1)Springboot自動配置很多組件時,先看容器中有沒有用戶自己配置的(@ConditionalOnMissingBean),如果有,就使用用戶配置的,如果沒有,才自動配置;

如果有些組件可以有多個(比如ViewResolver),就將用戶配置和自己默認的組合起來;


六、SpringBoot與Docker

1、Docker

  • Docker容器 是一個開源的應用容器引擎,基于Go語言并遵從Apache2.0協議開源,
  • Docker可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然后發布到任何流行的Linux機器上,也可以實作虛擬化
  • 容器完全使用沙箱機制,互相之間沒有任何介面
  • 容器性能開銷極低

2、核心概念:

docker主機(Host):安裝了Docker程式的機器(Docker直接安裝在作業系統上的),用于執行Docker守護行程和容器;

docker客戶端(Client):連接Docker主機進行操作;

docker倉庫(Registry):用來保存各種打包好的軟體鏡像;

docker鏡像(Images):軟體打包好的鏡像,放在Docker倉庫中

docker容器(Container):鏡像啟動后的實體,我們稱為一個容器;

3、使用步驟

  1. 安裝Docker;
  2. 去Docker倉庫找到要安裝軟體的鏡像;
  3. 使用Docker運行這個鏡像,這個鏡像就會生成一個Docker容器;
  4. 對容器的啟動停止,就是對軟體的啟動、停止;

4、安裝

  • Docker要求CentOS的內核版本高于3.10

查看內核版本:

uname -r

如果內核版本不夠,可以選擇升級軟體包以及內核:

yun update

安裝docker:

yum install docker

啟動Docker:

systemctl start docker

#檢查版本

docker -v

開機自啟動Docker:

systemctl enable docker

停止Docker

systemctl stop docker

5、Docker常用操作

(1)鏡像操作

這里以mysql為例

檢索鏡像

docker search mysql

拉取鏡像

docker pull mysql:5.5

#5.5是版本號

查看所有下載的鏡像:

docker images

洗掉鏡像

docker rmi 鏡像ID

(2)容器操作

得到軟體鏡像=》運行鏡像=》產生容器(正在運行的軟體)

根據鏡像啟動容器

docker run [--name 自定義容器名] -d(后臺運行) [-p(埠映射 ) 主機埠:容器埠] 鏡像名[:標簽(版本)]

docker run --name mytomcat -d -p 8080:8080 tomcat

查看運行中的鏡像

docker ps

查看所有容器

docker ps -a

停止運行中的容器

docker stop 容器名或者容器id

docker stop mytomcat

洗掉容器(必須是停止運行的容器)

docker rm 容器名或者容器id

docker rm mytomcat

七、SpringBoot與資料訪問

SpringBoot默認采用SpringData的方式進行統一處理,添加大量自動配置,屏蔽了很多設定,引入各種xxxtemplate,xxxRepository來簡化我們對資料庫訪問層的操作,

1、整合基本JDBC與資料源

#配置資料源
spring.datasource.driver-class-name        = com.mysql.cj.jdbc.Driver
spring.datasource.url                      = jdbc:mysql://localhost:3306/bookstore?serverTimezone=GMT
spring.datasource.username                 = rocke
spring.datasource.password                 = 123456789
@SpringBootTest
class JdbcApplicationTests {

    @Autowired
    DataSource dataSource;

    @Test
    void contextLoads() throws SQLException {
        System.out.println(dataSource.getClass());

        try(final Connection connection = dataSource.getConnection();){
            System.out.println("connection.getClass() = " + connection.getClass());
        }
    }

}

class com.zaxxer.hikari.HikariDataSource
connection.getClass() = class com.zaxxer.hikari.pool.HikariProxyConnection

2、JDBC-使用Druid資料源

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.4</version>
</dependency>
#配置資料源
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url               = jdbc:mysql://localhost:3306/bookstore?serverTimezone=GMT
spring.datasource.username          = rocke
spring.datasource.password          = 123456789
spring.datasource.type              = com.alibaba.druid.pool.DruidDataSource
#druid配置
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWai=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
#配置監控統計攔截的filters,,去掉監控界面sql無法統計,wall用于防火墻
spring.datasource.filters=stat,wall,log4j2
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.useGlobalDataSourceStat=true
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500



自己定義資料源,系結配置

@Configuration
public class DruidConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druid(){
        return new DruidDataSource();
    }
    
    //配置Druid的監控
    //1、配置管理后臺的監控Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        final ServletRegistrationBean<StatViewServlet> statViewServlet = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        final HashMap<String, String> initParams = new HashMap<>();
        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","12312037");
        initParams.put("allow","localhost");//不設定就默認允許所有
        statViewServlet.setInitParameters(initParams);
        return statViewServlet;
    }
    //2、配置一個監控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        final FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new WebStatFilter());
        final HashMap<String, String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Collections.singletonList("/*"));
        return bean;
    }
}

3、整合Mybatis

注解版

//指定這是一個操作資料庫的mapper
@Mapper
public interface BookMapper {

    @Select("select * from book where id=#{id}")
    //不推薦使用查詢注解,耦合性太高
    Book getBookById(Integer id);

}

注解聯合組態檔


八、SpringBoot啟動配置原理

幾個重要的配置原理:

配置在META-INF配置在spring.factories中的:

ApplicationContextInitializer

SpringApplicationRunListener

只需要放在ioc容器中的:

ApplicationRunner

CommandLineRunner

啟動流程:

1、創建SpringApplication物件

    public SpringApplication(Class<?>... primarySources) {
        this((ResourceLoader)null, primarySources);
    }

2、運行run方法

    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
        //獲取SpringApplicationRunListeners,從類路徑下的MEAT-INF/spring.factories
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        //回呼所有的SpringApplicationRunListeners的starting方法
        listeners.starting();
        Collection exceptionReporters;
        try {
            //封裝命令列引數
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            //準備環境
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            //創建ApplicationContext:決定創建web的ioc還是普通的ioc容器
            context = this.createApplicationContext();
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            //準備上下文環境:將environment保存到ioc容器中,而且applyInitializer():回呼之前保存的所有的ApplicationContextInitializer的initialize方法
            //回呼所有的SpringApplicationRunListener的ContextPrepare方法
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            //prepareContext運行完成后回呼所有的SpringApplicationRunListener的contextLoaded方法
            //重繪容器:ioc容器初始化的程序(如果是web應用,還會創建嵌入式的tomcat)
            //掃描、創建、加載所有組件的地方(配置類,組件(自動裝配))
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
            listeners.started(context);
            //從ioc容器中獲取所有的ApplicationRunner和CommandLineRunner,進行回呼
            //ApplicationRunner先回呼,再回呼CommandLineRunner
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            ///整個SpringBoot應用啟動后,回傳ioc容器
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

事件監聽機制的測驗

ApplicationContextInitializer

public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        System.out.println("ApplicationContextInitializer的initialize方法運行了.....");
    }
}

ApplicationRunner

@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("MyApplicationRunner的run方法呼叫了");
    }
}

CommandLineRunner

@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("MyCommandLineRunner的run方法運行了.....");
    }
}

SpringApplicationRunListener

public class MySpringApplicationListener implements SpringApplicationRunListener {

    public MySpringApplicationListener(SpringApplication application,String[] args) {
    }

    @Override
    public void starting() {
        System.out.println("MySpringApplicationListener的starting方法呼叫了");
    }

    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        System.out.println("environment.getSystemProperties().get(\"os.name\") = " + environment.getSystemProperties().get("os.name"));
        System.out.println("MySpringApplicationListener的environmentPrepared方法呼叫了");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("MySpringApplicationListener的contextPrepared方法呼叫了");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("MySpringApplicationListener的contextLoaded方法呼叫了");
    }

    @Override
    public void started(ConfigurableApplicationContext context) {
        System.out.println("MySpringApplicationListener的started方法呼叫了");
    }

    @Override
    public void running(ConfigurableApplicationContext context) {
        System.out.println("MySpringApplicationListener的running方法呼叫了");
    }

}

配置spring的factories

org.springframework.context.ApplicationContextInitializer=\
  com.example.mybatis.listener.MyApplicationContextInitializer
org.springframework.boot.SpringApplicationRunListener=\
  com.example.mybatis.listener.MySpringApplicationListener


九、自定義Starter

starter:場景啟動器

場景依賴

自動配置

啟動器模塊是一個空的jar檔案,僅提供輔助依賴管理,這些依賴可能用于自動裝配或者其他類別庫

啟動器依賴自動配置

命名規則:

自定義啟動器名-spring-boot-starter

......以后回來補,干設去了

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/260024.html

標籤:其他

上一篇:React基礎知識2

下一篇:PostgreSQL高可用中間件—Pgpool-Ⅱ

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more