SprintBoot學習(二)

Spring Boot的入口類
html

一、名爲xxxApplication的就是入口類,在main方法中使用SpringApplication.run(SpringBootTestApplication.class, args);啓動Spring Boot應用項目。java

二、@SpringBootApplication是由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan的組合註解。其中@EnableAutoConfiguration讓Spring Boot 根據類路徑中的jar包依賴爲當前項目進行自動配置。web

Spring Boot定製bannerspring

一、查找順序:依次在 Classpath 下找 文件 banner.gif , banner.jpg ,  banner.png 和 banner.txt,都沒有找到的話, 用默認的 SpringBootBanner , 就是咱們最多見到的那個。apache

 二、測試案例:安全

新banner.txtspringboot

${AnsiColor.BRIGHT_YELLOW}
////////////////////////////////////////////////////////////////////
//                                                                //
//                          ${AnsiColor.BRIGHT_RED}_ooOoo_${AnsiColor.BRIGHT_YELLOW}                               //
//                         ${AnsiColor.BRIGHT_RED}o8888888o${AnsiColor.BRIGHT_YELLOW}                              //
//                         ${AnsiColor.BRIGHT_RED}88${AnsiColor.BRIGHT_YELLOW}" . "${AnsiColor.BRIGHT_RED}88${AnsiColor.BRIGHT_YELLOW}                              //
//                         (| ^_^ |)                              //  
//                         O\  =  /O                              //  
//                      ____/`---'\____                           //  
//                    .'  \\|     |//  `.                         //  
//                   /  \\|||  :  |||//  \                        //  
//                  /  _||||| -:- |||||-  \                       //  
//                  |   | \\\  -  /// |   |                       //  
//                  | \_|  ''\---/''  |   |                       //  
//                  \  .-\__  `-`  ___/-. /                       //  
//                ___`. .'  /--.--\  `. . ___                     //  
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //  
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //  
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //  
//      ========`-.____`-.___\_____/___.-`____.-'========         //  
//                           `=---='                              //  
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //  
//            佛祖保佑       永不宕機     永無BUG                   //
////////////////////////////////////////////////////////////////////

運行結果:app

三、關閉banner框架

SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class); springApplication.setBannerMode(Banner.Mode.OFF); springApplication.run(args);

Spring Boot配置文件less

一、Spring Boot使用一個全局的配置文件application.properties 或application.yml,做用是對一些默認配置的配置值進行修改。

二、profile配置:輸Spring 針對不一樣的環境對不一樣的配置提供的支持,全局的profile配置使用application-{profile}.properties,經過application.properties中設置spring.profiles.active = prod來指定活動的profile。

測試案例:

spring.profiles.active=daily
#修改訪問路徑
server.servlet.context-path=/springboot
my.username=Amy

三、日誌配置:默認狀況下使用Logback作爲日誌框架

測試案例:

spring.profiles.active=daily
#修改訪問路徑
server.servlet.context-path=/springboot
my.username=Amy
#指定日誌文件保存地址
logging.file=D:/study/SpringBoot/log.log
debug=true

四、常規屬性配置:在Spring環境下須要用@PropertySource來指定文件的位置再用@Value來指定注入的值。再Spring Boot 中只須要用@Value的註解

配置文件:

ser.nikename=Saber
user.age=21

啓動類:

package com.example.spring_boot_test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @SpringBootApplication//開啓自動配置
public class SpringBootTestApplication { //經過@Value注入值
    @Value("${my.username}") private String userName; public static void main(String[] args) { //關閉banner
        /*SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class); springApplication.setBannerMode(Banner.Mode.OFF); springApplication.run(args);*/ SpringApplication.run(SpringBootTestApplication.class, args); } @RequestMapping("/") String index() { return "hello " + userName + " spring boot !!!"; } }

五、類型安全的配置:若是每次使用@Value註解逐一注入屬性會很麻煩,所以能夠經過@ConfigurationProperties將properties屬性和一個bean關聯起來,從而實現類型安全的配置。

配置文件:

ser.nikename=Saber
user.age=21

類型安全的Bean:

package com.example.spring_boot_test.entity; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component//要使用這個註解,這樣就能夠在 component scan時候被發現了,否則會沒法自動注入,
@PropertySource({"classpath:/my.properties"})//注意路徑的書寫格式
@ConfigurationProperties(prefix = "user") public class User { String nikename; int age; public String getNikename() { return nikename; } public void setNikename(String nikename) { this.nikename = nikename; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

啓動類:

package com.example.spring_boot_test; import com.example.spring_boot_test.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @SpringBootApplication//開啓自動配置
public class SpringBootTestApplication { @Autowired private User user; //經過@Value注入值
    @Value("${my.username}") private String userName; public static void main(String[] args) { //關閉banner
        /*SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class); springApplication.setBannerMode(Banner.Mode.OFF); springApplication.run(args);*/ SpringApplication.run(SpringBootTestApplication.class, args); } @RequestMapping("/") String index() { System.out.println(user.getNikename() + ":" + user.getAge()); return "hello " + userName + " spring boot !!!"; } }

Spring Boot運行原理

一、@SpringBootApplication是由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan的組合註解。核心功能由EnableAutoConfiguration提供。

  • @Configuration:@SpringBootConfiguration的本質是@Configuration,@Configuration至關於把該類做爲spring的xml配置文件中的<beans>,做用爲配置spring容器(應用上下文),任何一個標註了@Configuration的Java類定義都是一個JavaConfig配置類。
  • @ComponentScan:@ComponentScan自動掃描並加載符合條件的組件(好比@Component和@Repository等)或者bean定義,最終將這些bean定義加載到IoC容器中。
  • @EnableAutoConfiguration:@EnableAutoConfiguration的部分源碼以下:
    @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; } 

    其中@Import註解將全部符合自動配置條件的bean定義加載到IoC容器,AutoConfigurationImportSelector經過getCandidateConfigurations方法來掃描具備MWTA-INF/spring.factories文件的jar包(spring-boot-autoconfigure.jar),spring.factories文件聲明瞭自動配置。而後根據@EnableAutoConfiguration的完整類名org.springframework.boot.autoconfigure.EnableAutoConfiguration做爲查找的Key,獲取對應的一組@Configuration類,而後經過反射(Java Refletion)實例化爲對應的標註了@Configuration的JavaConfig形式的IoC容器配置類,最後彙總爲一個並加載到IoC容器。

Spring Boot執行流程

 

Spring Boot的執行流程主要分爲兩大部分:建立一個SpringApplication對象實例 ,調用這個建立好的SpringApplication的實例方法。

 一、建立一個SpringApplication對象實例

public SpringApplication(Class... primarySources) {
  //建立一個SpringApplication對象實例 this((ResourceLoader)null, primarySources); } public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) { this.sources = new LinkedHashSet(); this.bannerMode = Mode.CONSOLE; this.logStartupInfo = true; this.addCommandLineProperties = true; this.headless = true; this.registerShutdownHook = true; this.additionalProfiles = new HashSet(); this.isCustomEnvironment = false; this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); //推斷應用類型this.webApplicationType = this.deduceWebApplicationType(); //使用SpringFactoriesLoader在應用的classpath中查找並加載全部可用的ApplicationContextInitializer。 this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); //使用SpringFactoriesLoader在應用的classpath中查找並加載全部可用的ApplicationListener。 this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)); //經過拋出異常來獲取到異常棧從而獲得入口類的名稱設置main方法的定義類。 this.mainApplicationClass = this.deduceMainApplicationClass(); }

二、調用這個建立好的SpringApplication的實例方法

public ConfigurableApplicationContext run(String... args) {    //計時開始
    StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); this.configureHeadlessProperty(); //獲取全部經過SpringFactoriesLoader能夠查找到並加載的SpringApplicationRunListener
    SpringApplicationRunListeners listeners = this.getRunListeners(args); listeners.starting(); Collection exceptionReporters; try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); //建立並配置當前Spring Boot應用將要使用的Environment(包括配置要使用的PropertySource以及Profile)。 //遍歷調用全部SpringApplicationRunListener的environmentPrepared()的方法,告訴他們:「當前SpringBoot應用使用的Environment準備好了咯!」。
        ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments); this.configureIgnoreBeanInfo(environment); //是否打印banner
        Banner printedBanner = this.printBanner(environment); // 建立上下文對象,根據用戶是否明確設置了applicationContextClass類型以及初始化階段的推斷結果,決定該爲當前SpringBoot應用建立什麼類型的
        context = this.createApplicationContext();      //異常報警
        exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);      //spring上下文對象的前置處理
        this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);      //spring上下文對象的刷新
        this.refreshContext(context);      //spring上下文對象的後置處理
        this.afterRefresh(context, applicationArguments);      //計算器關閉
 stopWatch.stop(); if (this.logStartupInfo) { (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch); } //遍歷執行listeners,調用它們的started()方法,告訴這些SpringApplicationRunListener,「嘿,SpringBoot應用要開始執行咯!」。
 listeners.started(context); this.callRunners(context, applicationArguments); } catch (Throwable var10) { this.handleRunFailure(context, var10, exceptionReporters, listeners); throw new IllegalStateException(var10); } try { listeners.running(context); return context; } catch (Throwable var9) { this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null); throw new IllegalStateException(var9); }

Spring Boot中的starter pom

一、Spring Boot爲咱們提供了簡化企業級開發的絕大多數場景的stater pom,只要使用了應用場景所須要的starter pom就會獲得Spring Boot爲咱們提供的自動配置的bean。

二、自定義starter pom 測試案例:

  • 新建maven工程
    發尺寸

     填寫完工程名點擊finish,工程建立完成

  • 修改pom文件以下:
    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>spring-boot-starter-hello</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>1.4.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>1.4.3.RELEASE</version> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
  • 屬性配置:
    package com.example.spring_boot_starter_hello; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; //類型安全的屬性配置 @PropertySource({"classpath:/my.properties"})//注意路徑的書寫格式 @ConfigurationProperties(prefix = "hello") public class HelloServiceProperties { private static final String MSG="world"; private String msg=MSG; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }

    是類型安全的屬性配置與properties文件中的屬性相對應。

  • service類
    package com.example.spring_boot_starter_hello; public class HelloService { private String msg; public String sayHello(){ return "hello "+msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
  • 自動配置類
    package com.example.spring_boot_starter_hello; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //@Configuration標註在類上,至關於把該類做爲spring的xml配置文件中的<beans>,做用爲:配置spring容器(應用上下文)
    @Configuration //開啓屬性輸入
    @EnableConfigurationProperties(HelloServiceProperties.class) //判斷HelloService這個類在類路徑中是否存在,且在沒有這個bean的狀況下會自動配置這個bean
    @ConditionalOnClass(HelloService.class) //當設置hello=enable的狀況下,若是沒有設置默認爲true,即條件符合
    @ConditionalOnProperty(prefix = "hello",value = "enabled",matchIfMissing = true) public class HelloServiceAutoConfiguration { @Autowired private HelloServiceProperties helloServiceProperties; //使用Java配置的方式配置bean
     @Bean //當容器沒有這個bean的時候會新建bean
        @ConditionalOnMissingBean(HelloService.class) public HelloService helloService(){ HelloService helloService = new HelloService(); helloService.setMsg(helloServiceProperties.getMsg()); return helloService; } }
  • 註冊配置,在src/main/resources下新建META-INF/spring.factories,內容以下:
    #註冊自動配置類
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.example.spring_boot_starter_hello.HelloServiceAutoConfiguration
  • 使用starter 在以前的Spring Boot 中將自定義的starter做爲依賴,在pom文件中新增spring-boot-stater-hello的依賴。修改pom文件以下:
    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>spring-boot-test</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring_boot_test</name> <description>Demo project for Spring Boot</description> <!--spring boot的父級依賴--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--添加web依賴的起步依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--須要添加依賴ConfigurationProperties纔會起做用--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <!--添加spring-boot-stater-hello的依賴--> <dependency> <groupId>com.example</groupId> <artifactId>spring-boot-starter-hello</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <!--添加springboot的編譯插件--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

    經過mvn  install安裝到本地,或者發佈到遠程maven私服上。

  • 在properties文件中增長屬性:hello.msg=hello
  • 在Spring Boot中注入HelloService並使用
    package com.example.spring_boot_test; import com.example.spring_boot_starter_hello.HelloService; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController @SpringBootApplication//開啓自動配置 public class SpringBootTestApplication {  @Resource private HelloService helloService;
    public static void main(String[] args) { //關閉banner /*SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class); springApplication.setBannerMode(Banner.Mode.OFF); springApplication.run(args);*/ SpringApplication.run(SpringBootTestApplication.class, args); } @RequestMapping("hello") String hello() { return helloService.sayHello(); } }

轉載請於明顯處標明出處

https://www.cnblogs.com/AmyZheng/p/9791552.html

相關文章
相關標籤/搜索