走進JavaWeb技術世界16:極簡配置的SpringBoot

SpringBoot詳解(一)-快速入門

SpringBoot詳解系列文章:
SpringBoot詳解(一)-快速入門
SpringBoot詳解(二)-Spring Boot的核心
SpringBoot詳解(三)-Spring Boot的web開發
SpringBoot詳解(四)-優雅地處理日誌

1、Spring Boot

久聞Spring Boot大名,這兩天終於得空,學習了一把,發覺Spring Boot確實好用,那Spring Boot究竟是什麼,又是怎麼好用呢?css

什麼是Spring Boot

目前ssm框架仍是比較經常使用的,其中的ss指的無非就是Spring 和 SpringMVC,咱們能夠簡單的認爲 "Spring Boot ≥ Spring + SpringMVC",沒錯,用了Spring Boot中涵蓋了Spring和SpringMVC等大量經常使用開發配置,並且Spring Boot的配置極其簡單,可讓你不用或者只須要不多的Spring配置就可讓你的項目快速運行起來。html

Spring Boot的優缺點

優勢

  1. 快速構建項目
  2. 對主流開發框架的無配置集成
  3. 項目可獨立運行,無須外部依賴Servlet容器(Spring Boot默認自帶了一個Tomcat)
  4. 提供運行時的應用監控
  5. 極大地提升了開發、部署效率
  6. 與雲計算的自然集成

缺點

  1. 坑有些多, 文檔略少

2、快速入門

一、Spring的Java配置方式

上面已經提到了,使用Spring Boot,可讓你不用或者只須要不多的Spring配置就可讓你的項目快速運行起來,說的就是使用代碼註解來取代xml配置。其實從Spring3.x開始就已經提供了java配置方式,使用java配置方式能夠更好的理解你配置的Bean,而現在的Spring4.x更是推薦java配置方式,java配置方式能夠徹底替代xml配置,下面就先來看看兩個最基本的註釋:前端

1)@Configuration 和 @Bean

Spring的java配置方式是經過@Configuration 和 @Bean這兩個註釋實現的:java

  • @Configuration 做用於類上,至關於一個xml配置文件
  • @Bean 做用於方法上,至關於xml配置中的

2)小示例

該示例將經過java配置方式配置Spring,實現Spring IOC功能。

這是一個簡單的模擬從數據庫獲取User數據的Dao類(注意,它並無使用任何註解,也就是說UserDao目前並無交給Spring容器管理)。mysql

<pre>public class UserDao {
   public List<String> queryUserList() {
       List<String> list = new ArrayList<>();        for (int i = 0; i < 10; i++) {
           list.add("User " + i);
       }        return list;
   }
}
</pre>git

這是一個最最多見的Service,經過注入UserDao,使用UserDao的方法獲取用戶數據。程序員

<pre>@Service
public class UserService {github

   @Autowired
   UserDao userDao;web

   public void getUserList() {
       List<String> list = userDao.queryUserList();        for (int i = 0; i < list.size(); i++) {
           System.out.println(list.get(i));
       }
   }面試

}
</pre>

從這裏開始就跟以往的Spring開發不同了,這個類使用了2個新的註解,其中@Configuration代表該至關於Spring的一個xml配置文件,@Bean將一開始的UserDao配置給Spring管理.

<pre>@Configuration// 經過註解來代表該類是一個Spring的配置,至關於一個xml文件
public class SpringConfig {
   @Bean// 這裏要注意,方法名"getUserDao"將做爲UserDao在容器中的id
   public UserDao getUserDao() {        return new UserDao();
   }
}
</pre>

接下來就是獲取Spring容器,從容器中拿到UserService,並調用其獲取用戶數據的方法,代碼以下:

<pre>public class Test {
   public static void main(String[] args) {
       AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(SpringConfig.class);
       UserService userService = (UserService) acac.getBean("userService");
       userService.getUserList();
   }
}
</pre>

像普通的java程序同樣,直接運行Test類中的main方法便可在控制檯看到用戶數據輸出了。

細心的你應該發現了,以往獲取Spring容器使用到的類要麼是ClassPathXmlApplicationContext 或是 FileSystemXmlApplicationContext,但Spring Boot使用的倒是AnnotationConfigApplicationContext,緣由也好理解,由於咱們Spring Boot使用的是java配置的方式,而以往使用的是Spring的xml配置方式.

二、第一個Web應用

經過上面的示例,咱們已經知道了java配置方式是怎麼回事了,那接下來便正式開始使用Spring Boot來開發咱們的第一個web應用了.

1)pom.xml配置

設置spring boot的parent

<pre><parent>
   <groupId>org.springframework.boot</groupId>
   spring-boot-starter-parent
   <version>1.5.2.RELEASE</version>
</parent>
</pre>

說明:Spring boot的項目必需要將parent設置爲spring boot的parent,該parent包含了大量默認的配置,大大簡化了咱們的開發。

導入spring boot的web支持

<pre><dependency>
   <groupId>org.springframework.boot</groupId>
   spring-boot-starter-web
</dependency>
</pre>

添加Spring boot的插件

<pre><plugin>
   <groupId>org.springframework.boot</groupId>
   spring-boot-maven-plugin
</plugin>
</pre>

經過上面簡單的3步配置,Spring Boot就配置完畢了,相比以往的Spring、SpringMVC配置是否是要簡潔的多呢?

2)小示例

<pre>@SpringBootApplication// Spring Boot項目的核心註解,主要目的是開啓自動配置
@Controller//標明這是一個SpringMVC的Controller控制器
public class HelloApplication {

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

   // 在main方法中啓動一個應用,即:這個應用的入口
   public static void main(String[] args) {
       SpringApplication.run(HelloApplication.class, args);
   }

}
</pre>

通常Spring Boot的Web應用都有一個xxxApplication類,並使用@SpringBootApplication註解標記,做爲該web應用的加載入口。此外,還須要在main方法中(能夠是任意一個類)使用SpringApplication.run(xxxApplication.class, args)來啓動該web應用。

運行HelloApplication中的main()方法,啓動該web應用後,在地址欄輸入"http://localhost:8080/hello",就能夠看到輸出結果了。

3)運行報錯

若是你項目中沒有其餘配置,那在運行這個簡單的項目時通常是不會報錯的,但若是很不幸你第一次運行就報錯的話,也不用着急,大部分問題百度便可,本人在啓動項目過程當中遇到就"Cannot determine embedded database driver class for database type NONE"這樣的錯誤,這樣就記錄一下,報錯截圖以下:

緣由是:springboot啓動時會自動注入數據源和配置jpa。

解決方法:在@SpringBootApplication中排除其注入

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})

因此,上面的代碼修改以下便可:

<pre>@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
@Controller
public class HelloApplication {
   ...
}
</pre>

3、疑問

到這裏是否是已經大概感受到了Spring Boot的高效和簡潔了呢?配置就是如此簡單,功能就是如此強大,但經過上面一系列的講解,你是否是也產生一些疑惑呢,好比:

  1. Spring Boot的WEB應用默認端口就是8080,那這個端口要怎麼修改呢?
  2. 爲何會出現"Cannot determine embedded database driver class for database type NONE"這樣的錯誤?(或者說爲何springboot啓動時會自動注入數據源和配置jpa)
  3. 爲何@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})就能夠解決"Cannot determine embedded database driver class for database type NONE"這樣的錯誤呢?
  4. 既然Spring Boot的WEB應用默認使用的是自帶的Tomcat,那要怎麼部署到外部的Servlet容器呢?
  5. ...

不急,後續文章將會對這些問題一一解釋清楚。

SpringBoot詳解(二)-Spring Boot的核心

SpringBoot詳解系列文章:
SpringBoot詳解(一)-快速入門
SpringBoot詳解(二)-Spring Boot的核心
SpringBoot詳解(三)-Spring Boot的web開發
SpringBoot詳解(四)-優雅地處理日誌

Spring Boot的核心

在上篇中咱們成功運行了一個簡單的web應用,其中有一個註解被輕易的帶過了,但它在Spring Boot中是最重要的註解,沒有之一,它就是@SpringBootApplication,本篇將對它與Spring Boot的配置進行深刻的介紹。

一、@SpringBootApplication

前面已經說過了,通常Spring Boot的Web應用都有一個xxxApplication類,並使用@SpringBootApplication註解標記,做爲該web應用的加載入口。那這個@SpringBootApplication註解究竟是何方神聖?經過查看它的源碼,能夠發現它是一個組合註解:

@SpringBootApplication這個Spring Boot核心註解是由其它三個重要的註解組合,分別是: @SpringBootConfiguration 、 @EnableAutoConfiguration 和 @ComponentScan。

1)@SpringBootConfiguration

@SpringBootConfiguration是Spring Boot項目的配置註解,這也是一個組合註解。

經過上圖代碼,結合前面所講的知識,不難猜想出@SpringBootConfiguration與@Configuration存在着某種關係,能夠認爲@SpringBootConfiguration就至關於@Configuration,在Spring Boot項目中推薦使用@SpringBootConfiguration替代@Configuration,不過由於註釋長度問題,每每@Configuration較爲經常使用。

2)@EnableAutoConfiguration

@EnableAutoConfiguration註解用於啓用自動配置,該註解會使Spring Boot根據項目中依賴的jar包自動配置項目的配置項。

例如:上篇中,咱們在編寫第一個WEB應用時,就在pom.xml中引入了spring-boot-starter-web的依賴,因此項目中就會引入SpringMVC的依賴,就會自動配置tomcat和SpringMVC。

還有後面使用事務時,會引入spring-boot-starter-jdbc的依賴,讓Spring Boot自動配置DataSourceTransactionManager或JpaTransactionManager,等等。。

3)@ComponentScan

@ComponentScan是組件掃描註解,不配置默認掃描@SpringBootApplication所在類的同級目錄以及它的子目錄(這很重要,後面很應用到這個特性)。固然你也能夠本身指定要掃描的包目錄,例如:

<pre>@ComponentScan(basePackages = "com.lqr.demo1")
</pre>

二、取消部分自動配置

上面說了,Spring Boot根據項目中依賴的jar包自動配置項目的配置項,而Spring Boot支持的自動配置很是之多,以下圖所示(只是其中的一部分):

當自動配置的東西一多了,就容易出問題,上篇中最後出現的"Cannot determine embedded database driver class for database type NONE"錯誤,就是由於springboot啓動時會自動注入數據源和配置jpa,因此咱們就須要取消Spring Boot的部分自動配置。至於取消自動配置的方式也至關簡單,就是對@SpringBootApplication註解的exclude進行賦值便可,如:

<pre>@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
@Controller
public class HelloApplication {
   ...
}
</pre>

其餘的取消自動配置以此類推。

三、自定義Banner

這個知識點其實對開發意義不太,但不妨瞭解下(能夠裝個逼~~)。在Spring Boot項目啓動時,控制檯會輸出一個"spring>>>"的banner文字圖案,如:

這個banner是能夠自定義的,自定義的方法很簡單:只須要把想輸出的文字保存在banner.txt文件中,而後把這個banner.txt放到resources目錄下便可:

運行項目,而後控制檯就能夠輸出banner.txt中的文字了。

Text to ASCII Art Generator (TAAG)這個網站能夠獲得文字圖案。

四、Starter pom

Spring Boot爲咱們提供了簡化企業級開發絕大多數場景的start pom(相似於組件),只要使用了對應的starter pom,Spring Boot就會爲咱們提供自動配置的Bean。

這裏官方給出的starter,如下是"好心人"對這些Starter pom作的翻譯:

怎麼使用?直接在pom.xml中引入依賴便可(不懂請參考上篇中「第一個Web應用」中pom.xml配置的第二部分,或請自行百度)。

五、使用Xml配置文件

常規開發中,java配置方式已經能夠徹底取代xml配置方式了,但有時咱們並不想使用java配置,而是繼續沿用以前的xml配置方式,或者出於其餘緣由,必定要在xml中進行配置,那該怎麼辦呢,很簡單,使用@ImportResource註解便可:

<pre>@ImportResource(value = {"classpath:xxx1.xml","classpath:xxx2.xml"})
</pre>

六、全局配置文件

Spring Boot項目使用一個全局的配置文件application.properties或者是application.yml,在resources目錄下或者類路徑下的/config下,通常咱們放到resources下。

咱們知道Spring Boot會根據在pom.xml中依賴的jar包進行自動配置,當咱們要對這些jar包對應的框架進行配置又該怎麼辦呢,沒錯,能夠在全局配置文件(application.properties或者是application.yml)中進行配置,如tomcat的端口配置等。

1)全局配置文件的基本使用(application.properties)

這部分使用application.properties中的書寫方式來介紹。

①tomcat端口配置

<pre>server.port=8888
</pre>

②修改Spring MVC攔截路徑規則

默認Spring MVC攔截路徑規則是/,若是要修改爲*.html的話,能夠在全局配置文件中進行以下設置:

<pre>server.servlet-path=*.html
</pre>

③視圖解析器配置

同樣的,Spring Boot也能夠經過全局配置文件對視圖解析器進行配置:

<pre>spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
</pre>

④日誌輸出

Spring Boot對各類日誌框架都作了支持,咱們能夠經過配置來修改默認的日誌的配置:

<pre>#設置日誌級別logging.level.org.springframework=DEBUG
</pre>

2)全局配置文件的進階使用(application.yml)

這部分使用application.yml中的書寫方式來介紹。

properties與yml文件在形式上有所差異,yml文件的書寫方式比較簡潔,相似eclipse中package的flag呈現方式(而properties文件則像Hierarchical方式)。如上面properties文件中的屬性配置使用yml文件來寫:

<pre>server:
 port: 8080
 context-path: /

spring:
   mvc:
     view:
       prefix: /WEB-INF/views/
       suffix: .jsp

logging:
 level: debug
</pre>

yml文件在書寫時,須要注意一個地方:冒號與值中間是存在空格的!

①自定義屬性

全局配置文件並不僅是配置Spring Boot中已經存在的屬性,咱們也能夠自定義屬性(別忘了,它自己就是一個properties文件),代碼須要使用@Value("${xxx}")註解來獲取這些屬性,如:

②屬性引用屬性

屬性引用屬性也簡單,使用${xxx}就能夠引用配置文件中的屬性了。

<pre>lqr: 666
content: "${lqr} is six six six"
</pre>

③屬性轉對象

這個就比較有看點了,以上面的"server.port: 8080"爲例,咱們能夠認爲是Server這個類中有一個port屬性,其值爲8080。可使用@ConfigurationProperties(prefix = "屬性名前綴")這個註解做爲配置文件中屬性轉對象屬性的橋樑,具體如圖所示:

Spring Boot的全局配置很強大,同時它能夠配置的屬性也不少,以上只列出幾個經常使用的屬性配置,如需查看完整的全局屬性配置,請到spring-boot官方配置文檔查看。好了,本篇到此結束,主要介紹了Spring Boot中幾個核心註解與自動配置,同時解決上篇中的幾個問題,從下篇開始,將針對Spring Boot的web開發進行介紹。

SpringBoot詳解(三)-Spring Boot的web開發

SpringBoot詳解系列文章: 

SpringBoot詳解(一)快速入門 

SpringBoot詳解(二)-Spring Boot的核心 

SpringBoot詳解(三)-Spring Boot的web開發

1、web基礎配置

一、訪問靜態資源

1)進入規則爲 / 時

若是進入SpringMVC的規則爲/時,Spring Boot的默認靜態資源的路徑爲:

<pre>spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
</pre>

也就是說,在默認的Spring MVC進入規則下,classpath下的META-INF/resources目錄、resources目錄、static目錄和public目錄中的靜態資料是能夠直接經過 "http: // xxx.com/靜態資源" 的方式訪問到的。如:

2)進入規則爲*.xxx 或者 不指定靜態文件路徑時

若是進入SpringMVC的規則爲.xxx時(如:.html),則上述目錄下的靜態資源將沒法直接訪問,須要將靜態資源放置到webapp下的static目錄中便可經過 "http://xxx.com/static/靜態資源" 訪問。此外,默認不配置SpringMVC的規則下也能夠如此訪問,也就是說這種訪問靜態資源的方式是通用的。如圖所示:

二、自定義攔截器

增長一個攔截器,須要經過繼承WebMvcConfigurerAdapter而後重寫父類中的方法進行擴展。

<pre>@Configuration
public class MySpringMvcConfig extends WebMvcConfigurerAdapter {

   @Override
   public void addInterceptors(InterceptorRegistry registry) {
       HandlerInterceptor handlerInterceptor = new HandlerInterceptor() {
           @Override
           public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
               System.out.println("自定義攔截器。。。");
               return true;
           }

           @Override
           public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

           }

           @Override
           public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

           }
       };

// 添加攔截器並設置攔截規則

       registry.addInterceptor(handlerInterceptor).addPathPatterns("/**");
   }
}
</pre>

三、自定義消息轉化器

自定義消息轉化器有兩種實現方式,一種是@Bean方式,另外一種是自定義攔截器。

1)@Bean方式

只須要在@Configuration的類中添加消息轉化器的@bean加入到Spring容器,就會被Spring Boot自動加入到容器中。

<pre>// spring boot默認就有消息轉化器,其編碼格式爲utf-8
@Bean
public StringHttpMessageConverter stringHttpMessageConverter() {
   StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
   return stringHttpMessageConverter;
}
</pre>

2)自定義攔截器方式

WebMvcConfigurerAdapter的功能很強大,除了能夠配置攔截器外,還能夠配置消息轉換器。

<pre>@Configuration
public class MySpringMvcConfig extends WebMvcConfigurerAdapter {

   @Override
   public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
       StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
       converters.add(stringHttpMessageConverter);
   }
}
</pre>

四、讀取外部的配置文件

<pre>@Configuration
@PropertySource(value = { "classpath:jdbc.properties", "classpath:base.properties" }, ignoreResourceNotFound = true)
public class 任意類 {

}
</pre>

五、Druid DataSource的配置

Druid提供了一個高效、功能強大、可擴展性好的數據庫鏈接池,經常使用於替換DBCP和C3P0。但在Spring Boot上配置比較「噁心」,這裏就簡單的貼出我的參照網上的配置代碼,沒必要深究。

1)引入依賴

<pre><dependency>
   <groupId>com.alibaba</groupId>
   druid
   <version>1.0.11</version>
</dependency>
</pre>

2)jdbc.properties

項目中通常會建立一個jdbc.properties文件來記錄數據庫的鏈接信息。

<pre>#MySQL
jdbc.url=jdbc:mysql://127.0.0.1:3306/dbxxx?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456

Druid

jdbc.initialSize=0
jdbc.minIdle=0
jdbc.maxActive=150
</pre>

3)配置Druid數據源

建議將配置Druid數據源的操做放在@SpringBootApplication註解的類中。

<pre>@SpringBootApplication
@Configuration
@PropertySource(value = {"classpath:jdbc.properties"})
public class MyWebApplication{

   @Value("${jdbc.url}")
   public String jdbcUrl;
   @Value("${jdbc.username}")
   public String jdbcUsername;
   @Value("${jdbc.password}")
   public String jdbcPassword;
   @Value("${jdbc.initialSize}")
   public int jdbcInitialSize;
   @Value("${jdbc.minIdle}")
   public int jdbcMinIdle;
   @Value("${jdbc.maxActive}")
   public int jdbcMaxActive;

   @Bean
   public ServletRegistrationBean druidServletRegistrationBean() {
       ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
       servletRegistrationBean.setServlet(new StatViewServlet());
       servletRegistrationBean.addUrlMappings("/druid/*");
       return servletRegistrationBean;
   }

   @Bean
   public FilterRegistrationBean duridFilterRegistrationBean() {
       FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
       filterRegistrationBean.setFilter(new WebStatFilter());
       HashMap<String, String> initParams = new HashMap<>();
       // 設置忽略請求
       initParams.put("exclusions", ".js,.gif,.jpg,.bmp,.png,.css,.ico,/druid/");
       filterRegistrationBean.setInitParameters(initParams);
       filterRegistrationBean.addUrlPatterns("/*");
       return filterRegistrationBean;
   }

   @Bean(initMethod = "init", destroyMethod = "close")
   public DruidDataSource druidDataSource() {
       DruidDataSource druidDataSource = new DruidDataSource();
       druidDataSource.setUrl(jdbcUrl);
       druidDataSource.setUsername(jdbcUsername);
       druidDataSource.setPassword(jdbcPassword);
       druidDataSource.setInitialSize(jdbcInitialSize);
       druidDataSource.setMinIdle(jdbcMinIdle);
       druidDataSource.setMaxActive(jdbcMaxActive);
       return druidDataSource;
   }
}
</pre>

以後就能夠經過@AutoWried註解獲得數據源(druidDataSource)了。

六、數據庫框架集成

1)jpa集成

Jpa在使用上跟Hibernate很像,由於它們以前的關係非同通常,有興趣能夠看看《Hibernate與Jpa的關係,終於弄懂》這篇文章。Spring Boot對jpa的支持也是很好的,配置起來很是簡單。

在pom.xml中引用jpa及數據庫驅動(如:mysql)依賴

<pre><dependency>
   <groupId>org.springframework.boot</groupId>
   spring-boot-starter-data-jpa
</dependency>
<dependency>
   <groupId>mysql</groupId>
   mysql-connector-java
</dependency>
</pre>

在application.yml文件中配置

<pre>spring:
 datasource:
   driver-class-name: com.mysql.jdbc.Driver
   url: jdbc:mysql://127.0.0.1/dbgirl
   username: root
   password: 123456
 jpa:
   hibernate:
     ddl-auto: update  #第一次加載hibernate時根據model類會自動創建起表的結構(前提是先創建好數據庫),之後加載hibernate時根據 model類自動更新表結構,即便表結構改變了但表中的行仍然存在不會刪除之前的行。要注意的是當部署到服務器後,表結構是不會被立刻創建起來的,是要等 應用第一次運行起來後纔會。
   show-sql: true
</pre>

2)MyBatis集成

Mybatis和Spring Boot的整合有兩種方式:

第一種:使用mybatis官方提供的Spring Boot整合包實現,地址: spring-boot-starter

第二種:使用mybatis-spring整合的方式,也就是咱們傳統的方式

這裏推薦並使用第二種方式,由於能夠很方便的控制Mybatis的各類配置。這裏假設你已經配置過數據源了(數據源能夠是druid、dbcp、c3p0...)。

首先,須要在pom.xml文件中引用mybatis依賴

<pre><dependency>
   <groupId>org.mybatis</groupId>
   mybatis
   <version>3.3.0</version>
</dependency>
<dependency>
   <groupId>org.mybatis</groupId>
   mybatis-spring
   <version>1.2.2</version>
</dependency>
</pre>

而後,建立一個Mybatis的配置類:

<pre>@Configuration
public class MybatisConfig {

   @Autowired
   DruidDataSource druidDataSource;

   @Bean
   @ConditionalOnMissingBean// 當Spring容器中沒有SqlSessionFactoryBean時才建立
   public SqlSessionFactoryBean sqlSessionFactoryBean() {
       SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
       // 設置數據源
       sqlSessionFactory.setDataSource(druidDataSource);
       // 設置別名掃描包
       sqlSessionFactory.setTypeAliasesPackage("com.lqr.demo3.bean");
       // 設置Mybatis的配置文件位置
       PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
       Resource mybatisConfigXml = resolver.getResource("classpath:mybatis-config.xml");
       sqlSessionFactory.setConfigLocation(mybatisConfigXml);
       return sqlSessionFactory;
   }

}
</pre>

最後,建立Mapper接口的掃描類MapperScannerConfig:

<pre>@Configuration
@AutoConfigureAfter(MybatisConfig.class)// Mybatis的掃描配置必須在SqlSessionFactory被建立以後
public class MapperScanConfig {

   @Bean
   public MapperScannerConfigurer mapperScannerConfigurer() {
       MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
       mapperScannerConfigurer.setBasePackage("com.lqr.demo3.mapper");
       return mapperScannerConfigurer;
   }

}
</pre>

七、設置事務管理

Spring Boot中推薦使用@Transactional註解來申明事務。

<pre><dependency>

<groupId>org.springframework.boot</groupId>
spring-boot-starter-jdbc

</dependency>
</pre>

當引入jdbc依賴以後,Spring Boot會自動默認分別注入DataSourceTransactionManager或JpaTransactionManager,因此咱們不須要任何額外配置就能夠用@Transactional註解進行事務的使用。

<pre>@Service
@Transactional
public class GirlService {

   @Transactional
   public void insertGirl() {
       Girl girlA = new Girl();
       girlA.setCupSize("A");
       girlA.setAge(18);
       girlRespository.save(girlA);
   }
}
</pre>

@Transactional不只能夠註解在方法,也能夠註解在類上。當註解在類上時,意味着此類全部public方法都會開啓事務。若是類級別和方法級別同時使用了@Transactional註解,則使用在類級別的註解會重載方法級別的註解。

八、開啓jsp支持

Spring boot默認內嵌的tomcat是不支持jsp頁面的,若是項目中使用到了jsp,須要導入以下依賴才能正常訪問。

<pre><dependency>

<groupId>org.apache.tomcat.embed</groupId>
tomcat-embed-jasper
<scope>provided</scope>

</dependency>
</pre>

2、Web編碼進階

這部分可能跟Spring Boot的關係並非很大(或者說,並不是Spring Boot特有),但很值得咱們在編碼方面做爲參考。

一、Spring MVC中新的註解

1)@RestController

如今的Web項目已經愈來愈趨向於將後端與前端分別開發了,若是貴公司的項目就是使用json來進行先後端交互,且使用Spring MVC來開發的話,就必定會用到下面這2個註解:

<pre>@Controller
@ResponseBody
public class GirlController {

...

}
</pre>

而在Spring MVC4以後,咱們可使用@RestController 註解來開發基於Spring MVC4的REST風格的JSON服務。

通俗的說就是@RestController = @Controller + @ResponseBody。

@Controller和@RestController的區別:

若是隻是使用@RestController註解Controller,則Controller中的方法沒法返回jsp頁面,配置的視圖解析器InternalResourceViewResolver不起做用,返回的內容就是Return 裏的內容。 例如:原本應該到success.jsp頁面的,則其顯示success.

2)http組合註解

Spring4.3中引進了{@GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping},來幫助簡化經常使用的HTTP方法的映射,並更好地表達被註解方法的語義。

<pre>@GetMapping =>

@RequestMapping(value = "/xxx",method = RequestMethod.GET)

@PostMapping =>

@RequestMapping(value = "/xxx",method = RequestMethod.POST)

@PutMapping =>

@RequestMapping(value = "/xxx",method = RequestMethod.PUT)

@DeleteMapping =>

@RequestMapping(value = "/xxx",method = RequestMethod.DELETE)

...
</pre>

二、數據校驗

Web開發中,對從前端傳過來的數據作數據校驗已是屢見不鮮的事了,但若是校驗的數據不少,那麼,一方面在開發上就須要作不少if判斷,另外一方面則是代碼上顯得再也不簡潔。其實,使用@Valid + BindingResult就能夠優雅地解決這樣的問題。使用示例以下:

1)@Valid + BindingResult

首先,使用一個Java Bean來接收前端提交的數據。在這個Java Bean以前加上@Valid,在這個Java Bean以後加上BindingResult(BindingResult參數必須緊跟在@Valid參數以後。)

<pre>/**

  • 添加一個女生

*/
@PostMapping(value = "/girls")
public Result<Girl> girlAdd(@Valid Girl girl, BindingResult bindingResult) {
   if (bindingResult.hasErrors()) {
       return ResultUtils.error(-1, bindingResult.getFieldError().getDefaultMessage());
   }
   return ResultUtils.success(girlRespository.save(girl));
}
</pre>

2)設置校驗規則

而後,須要在@Valid註解的Java Bean中,使用各類"規則註解"對其中的屬性進行校驗規則的設定。示例以下:

<pre>public class Girl {

   private Integer id;

   @NotBlank(message = "這個字段必傳")
   private String cupSize;

   @Min(value = 18, message = "未成年少女禁止入內")
   private Integer age;

   @NotNull(message = "金額必傳")
   private Double money;

   ...
}
</pre>

示例中,"規則註解"的message值能夠在Controller中經過bindingResult.getFieldError().getDefaultMessage()獲取。

這類用於數據校驗的註解還有不少,有興趣的能夠好好研究一下:

註解 類型 說明
@AssertFalse Boolean,boolean 驗證註解的元素值是false
@AssertTrue Boolean,boolean 驗證註解的元素值是true
@NotNull 任意類型 驗證註解的元素值不是null
@Null 任意類型 驗證註解的元素值是null
@Min(value=值) BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存儲的是數字)子類型 驗證註解的元素值大於等於@Min指定的value值
@Max(value=值) 和@Min要求同樣 驗證註解的元素值小於等於@Max指定的value值
@DecimalMin(value=值) 和@Min要求同樣 驗證註解的元素值大於等於@ DecimalMin指定的value值
@DecimalMax(value=值) 和@Min要求同樣 驗證註解的元素值小於等於@ DecimalMax指定的value值
@Digits(integer=整數位數, fraction=小數位數) 和@Min要求同樣 驗證註解的元素值的整數位數和小數位數上限
@Size(min=下限, max=上限) 字符串、Collection、Map、數組等 驗證註解的元素值的在min和max(包含)指定區間以內,如字符長度、集合大小
@Past java.util.Date,java.util.Calendar;Joda Time類庫的日期類型 驗證註解的元素值(日期類型)比當前時間早
@Future 與@Past要求同樣 驗證註解的元素值(日期類型)比當前時間晚
@NotBlank CharSequence子類型 驗證註解的元素值不爲空(不爲null、去除首位空格後長度爲0),不一樣於@NotEmpty,@NotBlank只應用於字符串且在比較時會去除字符串的首位空格
@Length(min=下限, max=上限) CharSequence子類型 驗證註解的元素值長度在min和max區間內
@NotEmpty CharSequence子類型、Collection、Map、數組 驗證註解的元素值不爲null且不爲空(字符串長度不爲0、集合大小不爲0)
@Range(min=最小值, max=最大值) BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子類型和包裝類型 驗證註解的元素值在最小值和最大值之間
@Email(regexp=正則表達式,flag=標誌的模式) CharSequence子類型(如String) 驗證註解的元素值是Email,也能夠經過regexp和flag指定自定義的email格式
@Pattern(regexp=正則表達式,flag=標誌的模式) String,任何CharSequence的子類型 驗證註解的元素值與指定的正則表達式匹配
@Valid 任何非原子類型 指定遞歸驗證關聯的對象;如用戶對象中有個地址對象屬性,若是想在驗證用戶對象時一塊兒驗證地址對象的話,在地址對象上加@Valid註解便可級聯驗證

三、面積切面編程(AOP配置)

AOP是Spring中一大核心,若在SpringBoot中要使用AOP只需兩步:

1)引入AOP的starter依賴

<pre><dependency>
   <groupId>org.springframework.boot</groupId>
   spring-boot-starter-aop
</dependency>
</pre>

2)編寫切面類

<pre>@Aspect
@Component
public class HttpAspect {
   private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);

   @Pointcut("execution(public com.lqr.controller.GirlController.(..))")
   public void log() {
   }

   @Before("log()")
   public void deBefore(JoinPoint joinPoint) {
       ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
       HttpServletRequest request = attributes.getRequest();

       // url
       logger.info("url={}", request.getRequestURL());
       // method
       logger.info("method={}", request.getMethod());
       // ip
       logger.info("ip={}", request.getRemoteAddr());
       // 類方法
       logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
       // 參數
       logger.info("args={}", joinPoint.getArgs());

   }

   @After("log()")
   public void doAfter() {
       logger.info("doAfter...");
   }

   @AfterReturning(returning = "object", pointcut = "log()")
   public void doAfterReturning(Object object) {
       if (object != null)
           logger.info("response={}", object.toString());
   }

}
</pre>

四、統一異常處理(配置通知Advice)

1)自定義異常

這裏之因此繼承RuntimeException,是爲了方便事務回滾。而自定義異常的好處在於:一方面可使代碼語義化,另外一方面使得咱們編碼更加方便。

<pre>public class GirlException extends RuntimeException {
   private Integer code;

   public GirlException(ResultEnum resultEnum) {
       super(resultEnum.getMsg());
       this.code = resultEnum.getCode();
   }

   public Integer getCode() {
       return code;
   }

   public void setCode(Integer code) {
       this.code = code;
   }
}
</pre>

2)配置全局異常捕獲器

使用全局異常捕獲器,一方面能夠捕獲到整個項目中的Exception及其子類(包含RuntimeException等),另外一方面能夠對異常進行統一處理並返回統一的數據格式,爲前端提供友好的數據交互。

<pre>@ControllerAdvice
public class ExceptionHandle {

   private final Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);

   @ExceptionHandler(value = Exception.class)
   @ResponseBody
   public Result handle(Exception e) {
       if (e instanceof GirlException) {
           GirlException girlException = (GirlException) e;
           return ResultUtils.error(girlException.getCode(), girlException.getMessage());
       } else {
           logger.error("【系統異常】{}", e);
           return ResultUtils.error(-1, "未知錯誤");
       }
   }

}
</pre>

3、開發與生產

一、熱部署

Web開發中,沒有熱部署怎麼能行呢?因此,下面就介紹下Spring Boot的熱部署配置。

1)在pom.xml中配置熱部署須要的依賴與插件

<pre><dependencies>
   ...
   <!--spring boot 熱部署-->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       spring-boot-devtools
       <optional>true</optional>
   </dependency>
</dependencies>
<build>
   <plugins>
       <!--spring boot 熱部署-->
       <plugin>
           <groupId>org.springframework.boot</groupId>
           spring-boot-maven-plugin
           <configuration>
               <fork>true</fork>
           </configuration>
       </plugin>
   </plugins>

...

</build>
</pre>

2)開啓自動編譯

打開Idea的Settings界面,找到"Build,Execution,Depolyment",在Compiler中將"Build project automatically"打鉤。

3)修改pom.xml的維護(Maintenance)登記項

使用快捷鍵 "ctrl+shift+alt+/" 打開pom.xml的維護(Maintenance)菜單,找到登記(registry)項,單擊打開。

4)容許應用程序運行時自動編譯

在登記(registry)中找到"compiler.automake.allow.when.app.running"這一項打鉤,關閉。最後重啓項目便可!!!

二、發佈到獨立的tomcat中運行

儘管Spring Boot項目會內置一個tomcat,僅只需經過一個簡單的指令即可啓動項目,但在生產環境下,咱們仍是習慣將項目發佈到第三外的servlet容器中,下面將介紹若是將一個Spring Boot項目團部署到第三方tomcat中運行。

1)修改工程的打包方式爲war

2)將spring-boot-starter-tomcat的範圍設置爲provided

spring-boot-starter-tomcat是Spring Boot默認就會配置的,即上面說到的內嵌tomcat,將其設置爲provided是在打包時會將該包(依賴)排除,由於要放到獨立的tomcat中運行,Spring Boot內嵌的Tomcat是不須要用到的。

<pre><!--spring boot tomcat(默承認以不用配置,但當須要把當前web應用佈置到外部servlet容器時就須要配置,並將scope配置爲provided)-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   spring-boot-starter-tomcat
   <scope>provided</scope>
</dependency>
</pre>

3)修改代碼,設置啓動配置

須要繼承SpringBootServletInitializer,並重寫configure()方法,將Spring Boot的入口類設置進去。

<pre>// 若要部署到外部servlet容器,須要繼承SpringBootServletInitializer並重寫configure()
@SpringBootApplication
@Configuration
public class MyWebApplication extends SpringBootServletInitializer
{

   @Override
   protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
       // 設置啓動類,用於獨立tomcat運行的入口
       return builder.sources(MyWebApplication.class);
   }
}
</pre>

4)打war包並部署到tomcat

一位阿里 Java 工程師的技術小站。做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!(關注公衆號後回覆」Java「便可領取 Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源)

微信公衆號【黃小斜】大廠程序員,互聯網行業新知,終身學習踐行者。關注後回覆「Java」、「Python」、「C++」、「大數據」、「機器學習」、「算法」、「AI」、「Android」、「前端」、「iOS」、「考研」、「BAT」、「校招」、「筆試」、「面試」、「面經」、「計算機基礎」、「LeetCode」 等關鍵字能夠獲取對應的免費學習資料。 

                     

相關文章
相關標籤/搜索