Spring Boot 入門

Spring Boot自動配置 

http://blog.javachen.com/2015/03/13/how-to-run-spring-boot-application.html html

http://blog.javachen.com/2015/03/13/some-spring-boot-features.htmljava

http://blog.javachen.com/2016/02/19/spring-boot-auto-configuration.html mysql

 

在上篇文章如何運行Spring Boot應用中,已經熟悉瞭如何經過maven或者gradle建立一個Spring Boot應用,這篇文章主要學習Spring Boot的自動配置,包括註解的使用以及一些配置約束等等。git

關於Spring Boot的特性介紹,能夠參考Spring Boot特性github

主應用類

在Spring Boot應用中,咱們一般將主應用類放置於應用的根包中,例如,com.javachen.example。主應用類有main方法,而且使用了@EnableAutoConfiguration註解,並暗地裏定義了一個基礎的包路徑,Spring Boot會在該包路徑來搜索類。例如,若是你正在編寫一個JPA應用,被@EnableAutoConfiguration註解的類所在包將被用來搜索帶有@Entity註解的實體類。web

在主應用類上指定@ComponentScan,一樣也隱式的指定了掃描時basePackage的路徑。算法

如何運行Spring Boot應用中Application.java類聲明瞭main方法,還使用了@EnableAutoConfiguration註解。spring

@RestController
@EnableAutoConfiguration
public class Application {
  @RequestMapping("/")
  String home() {
    return "Hello World!";
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }
}
pasting

 

說明:sql

  • @RestController@RequestMapping註解是Spring MVC註解,它們不是Spring Boot的特定部分,具體查看Spring參考文檔的MVC章節。
  • @EnableAutoConfiguration這個註解告訴Spring Boot根據添加的jar依賴猜想你想如何配置Spring。因爲spring-boot-starter-web添加了Tomcat和Spring MVC,因此auto-configuration將假定你正在開發一個web應用並相應地對Spring進行設置。

配置類

在該類上也能夠使用@Configuration註解,用來對spring boot進行配置,固然,你也能夠使用一個XML源來調用SpringApplication.run()進行配置。數據庫

標有@Configuration註解的類爲配置類。你不須要將全部的@Configuration放進一個單獨的類。@Import註解能夠用來導入其餘配置類。另外,你也能夠使用@ComponentScan註解自動收集全部的Spring組件,包括@Configuration類。

若是你須要使用基於XML的配置,你能夠在注有@Configuration的類上使用附加的@ImportResource註解加載XML配置文件。

你能夠經過將@EnableAutoConfiguration@SpringBootApplication註解添加到一個@Configuration類上來選擇自動配置。自動配置的意思是Spring Boot嘗試根據你添加的jar依賴自動配置你的Spring應用。

若是須要找出當前應用了哪些自動配置及應用的緣由,你能夠使用--debug開關啓動應用,這將會記錄一個自動配置的報告並輸出到控制檯。

若是發現應用了你不想要的特定自動配置類,你能夠使用@EnableAutoConfiguration註解的排除屬性來禁用它們。

import org.springframework.boot.autoconfigure.*; import org.springframework.boot.autoconfigure.jdbc.*; import org.springframework.context.annotation.*;  @Configuration @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) public class MyConfiguration { }

總結,上面提到了幾個註解,用途分別以下:

  • @Configuration。標註一個類爲配置類。
  • @EnableAutoConfiguration。開啓自動配置。
  • @SpringBootApplication。等價於以默認屬性使用@Configuration@EnableAutoConfiguration@ComponentScan

若是啓動類在根包下面,則你能夠在該類上添加@ComponentScan註解而不須要添加任何參數,Spring Boot會在根包下面搜索注有@Component@Service,@Repository@Controller註解的全部類,並將他們註冊爲Spring Beans,不然,你須要在@ComponentScan註解上定義basePackages或者其餘屬性。

這樣Application.java能夠定義爲:

package com.javachen.example;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;  @RestController @Configuration @ComponentScan @EnableAutoConfiguration public class Application {   @RequestMapping("/")   String home() {     return "Hello World!";   }    public static void main(String[] args) throws Exception {     SpringApplication.run(Application.class, args);   } }

或者:

package com.javachen.example;  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 Application {   @RequestMapping("/")   String home() {     return "Hello World!";   }    public static void main(String[] args) throws Exception {     SpringApplication.run(Application.class, args);   } }

命令行參數

啓動類能夠實現CommandLineRunner接口,經過run方法處理main方法傳入的參數,而且你可以使用@Value註解將命令行參數傳入的值或者properties資源文件中定義的值注入到程序中。例如,建立一個HelloWorldService類:

package com.javachen.example.service;  import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;  @Component public class HelloWorldService {   @Value("${name:World}")   private String name;    public String getMessage() {     return "Hello " + this.name;   } }

並添加資源文件application.properties:

name: JavaChen

修改Application類爲以下:

package com.javachen.example;  import com.javachen.example.service.HelloWorldService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; 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 Application implements CommandLineRunner {   @Autowired   private HelloWorldService helloWorldService;    @RequestMapping("/")   String home() {     return "Hello World!";   }    @Override   public void run(String... args) {     System.out.println(this.helloWorldService.getMessage());     if (args.length > 0 && args[0].equals("exitcode")) {       throw new ExitException();     }   }    public static void main(String[] args) throws Exception {     SpringApplication.run(Application.class, args);   } }

運行該類的main方法,則默認會輸出:

Hello JavaChen

再次運行main方法,並傳入參數--name=whatever,則會輸出:

Hello whatever

若是一些CommandLineRunner beans被定義必須以特定的次序調用,你能夠額外實現org.springframework.core.Ordered接口或使用@Order註解。

利用command-line runner的這個特性,再配合依賴注入,能夠在應用程序啓動時後首先引入一些依賴bean,例如data source、rpc服務或者其餘模塊等等,這些對象的初始化能夠放在run方法中。不過,須要注意的是,在run方法中執行初始化動做的時候一旦遇到任何異常,都會使得應用程序中止運行,所以最好利用try/catch語句處理可能遇到的異常。

每一個SpringApplication在退出時爲了確保ApplicationContext被優雅的關閉,將會註冊一個JVM的shutdown鉤子。全部標準的Spring生命週期回調(好比,DisposableBean接口或@PreDestroy註解)都能使用。

此外,若是beans想在應用結束時返回一個特定的退出碼,能夠實現org.springframework.boot.ExitCodeGenerator接口,例如上面例子中的ExitException異常類:

package com.javachen.example;  import org.springframework.boot.ExitCodeGenerator;  public class ExitException extends RuntimeException implements ExitCodeGenerator {   @Override   public int getExitCode() {     return 10;   } }

自動配置

在啓動類上使用@EnableAutoConfiguration註解,就會開啓自動配置,簡單點說就是它會根據定義在classpath下的類,自動的給你生成一些Bean,並加載到Spring的Context中。

它的神祕之處,不在於它能作什麼,而在於它會生成什麼樣的Bean對於開發人員是不可預知(或者說不容易預知)。

例如,上面例子中引入了對spring-boot-starter-web的依賴,則會開啓Spring MVC自動配置,觀察啓動日誌,能夠發現應用啓動了tomcat和spring mvc。

Spring Boot爲Spring MVC提供適用於多數應用的自動配置功能。在Spring默認基礎上,自動配置添加了如下特性:

  • 引入ContentNegotiatingViewResolver和BeanNameViewResolver beans。
  • 對靜態資源的支持,包括對WebJars的支持。
  • 自動註冊Converter,GenericConverter,Formatter beans。
  • 對HttpMessageConverters的支持。
  • 自動註冊MessageCodeResolver。
  • 對靜態index.html的支持。
  • 對自定義Favicon的支持。

若是想全面控制Spring MVC,你能夠添加本身的@Configuration,並使用@EnableWebMvc對其註解。若是想保留Spring Boot MVC的特性,並只是添加其餘的MVC配置(攔截器,formatters,視圖控制器等),你能夠添加本身的WebMvcConfigurerAdapter類型的@Bean(不使用@EnableWebMvc註解)。

再舉個例子:要開發一個基於Spring JPA的應用,會涉及到下面三個Bean的配置,DataSource,EntityManagerFactory,PlatformTransactionManager。

@Configuration @EnableJpaRepositories @EnableTransactionManagement public class Application {   @Bean   public DataSource dataSource() {       ...   }    @Bean   public EntityManagerFactory entityManagerFactory() {       ..       factory.setDataSource(dataSource());       return factory.getObject();   }    @Bean   public PlatformTransactionManager transactionManager() {       JpaTransactionManager txManager = new JpaTransactionManager();       txManager.setEntityManagerFactory(entityManagerFactory());       return txManager;   } }

說明:

  • @EnableJpaRepositories會查找知足做爲Repository條件(繼承父類或者使用註解)的類。
  • @EnableTransactionManagement的做用:Enables Spring’s annotation-driven transaction management capability, similar to the support found in Spring’s <tx:*> XML namespace。

可是,若是你使用了@EnableAutoConfiguration,那麼上面三個Bean,你都不須要配置。在classpath下面只引入了MySQL的驅動和SpringJpa。

compile 'mysql:mysql-connector-java:5.1.18' compile 'org.springframework.boot:spring-boot-starter-data-jpa'

在生產環境中,數據庫鏈接能夠使用DataSource池進行自動配置。下面是選取一個特定實現的算法:

  • 因爲Tomcat數據源鏈接池的性能和併發,在tomcat可用時,咱們老是優先使用它。
  • 若是HikariCP可用,咱們將使用它。
  • 若是Commons DBCP可用,咱們將使用它,但在生產環境不推薦使用它。
  • 最後,若是Commons DBCP2可用,咱們將使用它。

若是你使用spring-boot-starter-jdbc或spring-boot-starter-data-jpa,你將會自動獲取對tomcat-jdbc的依賴。

DataSource配置經過外部配置文件的spring.datasource.*屬性控制。示例中,你可能會在application.properties中聲明下面的片斷:

spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=dbuser spring.datasource.password=dbpass spring.datasource.driver-class-name=com.mysql.jdbc.Driver

其餘可選的配置能夠查看DataSourceProperties。同時注意你能夠經過spring.datasource.*配置任何DataSource實現相關的特定屬性:具體參考你使用的鏈接池實現的文檔。

既然Spring Boot可以從大多數數據庫的url上推斷出driver-class-name,那麼你就不須要再指定它了。對於一個將要建立的DataSource鏈接池,咱們須要可以驗證Driver是否可用,因此咱們會在作任何事情以前檢查它。好比,若是你設置spring.datasource.driverClassName=com.mysql.jdbc.Driver,而後這個類就會被加載。

Spring的JdbcTemplate和NamedParameterJdbcTemplate類是被自動配置的,你能夠在本身的beans中經過@Autowire直接注入它們。

若是數據源是jndi,則定義:

spring.datasource.jndi-name=java:jboss/datasources/customers

XML配置

若是不想使用註解進行配置,則能夠使用xml配置文件,修改main方法以下:

public static void main(String[] args) throws Exception {     SpringApplication.run("classpath:/META-INF/application-context.xml", args);   }

META-INF/application-context.xml文件以下:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:context="http://www.springframework.org/schema/context"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">      <context:annotation-config/>     <context:property-placeholder/>      <bean id="helloService" class="com.javachen.example.service.HelloWorldService"/>     <bean id="application" class="com.javachen.example.Application"/>  </beans>
相關文章
相關標籤/搜索