摘要
看完本文你將掌握如下知識(shí)點(diǎn):
- 如何搭建一個(gè)SpringBoot項(xiàng)目
- SpringBoot自動(dòng)配置原理
- SpringBoot屬性配置方法
- 修改默認(rèn)的Logback日志為log4j和log4j2的方法
- 修改默認(rèn)的內(nèi)置tomcat容器為Jetty容器和Undertow容器的方法
- SpringBoot單元測(cè)試方法
- 使用war包運(yùn)行項(xiàng)目
SpringBoot系列:Spring Boot學(xué)習(xí)筆記
Spring Boot簡(jiǎn)介
- 要我給Spring Boot做個(gè)定義咳燕,簡(jiǎn)單來(lái)說(shuō)就是一個(gè)基于強(qiáng)大的Spring框架的、推崇JavaConfig的極簡(jiǎn)配置的web開(kāi)發(fā)框架;
- Spring Boot通過(guò)內(nèi)嵌Servlet容器(Tomcat控乾、Jetty,等等)的方式慨仿,可以以jar包的形式獨(dú)立運(yùn)行一個(gè)web項(xiàng)目帘撰;
- Spring Boot提倡JavaConfig和注解的零配置方式摧找,并且默認(rèn)配置滿足絕大多數(shù)場(chǎng)景的需要,意味著少量修改默認(rèn)配置即可快速搭建一個(gè)web項(xiàng)目减余,極大的提高開(kāi)發(fā)效率综苔;
- 項(xiàng)目中加入某一個(gè)
spring-boot-starter-*
依賴,就可以引入該功能的完整jar包佳励,降低pom的復(fù)雜度 - 本文基于Spring Boot的版本為1.4.2.RELEASE
Spring Boot項(xiàng)目創(chuàng)建方法
- http://start.spring.io:可以通過(guò)網(wǎng)頁(yè)創(chuàng)建項(xiàng)目結(jié)構(gòu)并下載休里;
- Spring Boot CLI:通過(guò)命令行的方式創(chuàng)建Spring Boot項(xiàng)目;
- Spring Tool Suite:習(xí)慣Eclipse的用戶可以使用STS創(chuàng)建『Spring Starter Project』項(xiàng)目;
- IntelliJ IDEA:強(qiáng)大的生產(chǎn)力工具赃承,推薦使用,創(chuàng)建『Spring Initializr』項(xiàng)目;
使用IntelliJ IDEA創(chuàng)建一個(gè)web項(xiàng)目
-
新建Spring Initializr項(xiàng)目
說(shuō)明:Spring Boot要求JDK1.6+
-
填寫(xiě)項(xiàng)目信息妇垢,構(gòu)建工具使用maven
-
選擇項(xiàng)目使用的依賴,這里我們只需要勾選web
- Spring Boot當(dāng)前最新的穩(wěn)定版是1.4.2创橄;
- 所有依賴可以在創(chuàng)建時(shí)勾選圃酵,也可以在創(chuàng)建后手工將依賴添加到pom中,如果對(duì)依賴比較熟悉豁状,推薦手工添加,這樣可以加快創(chuàng)建項(xiàng)目的時(shí)間;
-
填寫(xiě)項(xiàng)目名稱矿卑,點(diǎn)擊Finish
-
新建的項(xiàng)目結(jié)構(gòu)如下
SpringBoot項(xiàng)目只會(huì)在項(xiàng)目根目錄下生成一個(gè)類--SpringBootWebDemoApplication(artifactId+Application),它就是一個(gè)帶有main函數(shù)的啟動(dòng)類噩茄;
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootWebDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebDemoApplication.class, args);
}
}
- pom.xml說(shuō)明
<?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>springbootwebdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBootWebDemo</name>
<description>Demo project for Spring Boot</description>
<!-- 創(chuàng)建的Springboot項(xiàng)目需要繼承于spring-boot-starter-parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.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>
<!-- 創(chuàng)建項(xiàng)目是勾選的web依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 每個(gè)項(xiàng)目都會(huì)自動(dòng)添加一個(gè)test依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Springboot的編譯插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
這就是一個(gè)web項(xiàng)目的pom文件,可以看到只關(guān)聯(lián)了很少的依賴译红,這是因?yàn)槲覀兝^承的spring-boot-starter-parent和關(guān)聯(lián)的spring-boot-starter-web本身已經(jīng)為我們關(guān)聯(lián)了全部的依賴膘怕,如下是該項(xiàng)目所有的依賴包
運(yùn)行Spring Boot項(xiàng)目
- maven運(yùn)行:
mvn spring-boot:run
娘荡; - main函數(shù)運(yùn)行:右鍵單擊SpringBootWebDemoApplication,選擇『Run 或者 Debug』;
- 推薦安裝JRebel插件庞溜,支持熱部署外构;
- 當(dāng)然妻率,也可以maven先打成jar,然后通過(guò)命令行執(zhí)行
java -jar xx.jar
;
運(yùn)行成功會(huì)看到控制臺(tái)打印了如下信息
可以看到打印信息中有tomcat的啟動(dòng)信息携兵,說(shuō)明springboot默認(rèn)使用tomcat作為web運(yùn)行容器愈涩,這點(diǎn)從上面的依賴包中也可以看到鸠窗。因?yàn)楫?dāng)前項(xiàng)目并沒(méi)有開(kāi)放任何服務(wù)星持,所以此時(shí)訪問(wèn)8080端口會(huì)提示無(wú)服務(wù)
添加服務(wù)
- 我們可以在項(xiàng)目中創(chuàng)建一個(gè)Controller控制器乍迄,比如DemoController
package com.example.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@RequestMapping("/")
String index(){
return "Hello Spring Boot!";
}
}
- 運(yùn)行SpringBootWebDemoApplication,再次訪問(wèn)http://localhost:8080
一切似乎就是那么美好绿店,我們什么都沒(méi)配置,一個(gè)web項(xiàng)目就這樣運(yùn)行起來(lái)了,SpringBoot自動(dòng)幫我們默認(rèn)了一些常用的配置
自動(dòng)配置原理說(shuō)明
SpringBootWebDemoApplication類上的注解:@SpringBootApplication
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AliasFor;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
Class<?>[] exclude() default {};
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
}
- @SpringBootConfiguration實(shí)際上就是@Configuration,說(shuō)明這是一個(gè)JavaConfig
- @ComponentScan添谊,啟用注解自動(dòng)掃描
- @EnableAutoConfiguration的作用是根據(jù)類路徑中jar包是否存在來(lái)決定是否開(kāi)啟某一個(gè)功能的自動(dòng)配置陆蟆,比如胖腾,我們項(xiàng)目中添加了spring-boot-starter-web依賴,因其關(guān)聯(lián)Tomcat和Srping MVC,所以類路徑下就會(huì)存在Tomcat和Spring MVC的jar包,SpringBoot項(xiàng)目掃描到這些jar包后會(huì)自動(dòng)開(kāi)啟兩者的配置知举,當(dāng)然边坤,這個(gè)配置是默認(rèn)配置,我們可以根據(jù)需要進(jìn)行修改(下文介紹)谅年。
- exclude和excludeName用于關(guān)閉指定的自動(dòng)配置惩嘉,比如關(guān)閉數(shù)據(jù)源相關(guān)的自動(dòng)配置
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
- scanBasePackages和scanBasePackageClasses用于指定掃描的路徑,默認(rèn)情況下會(huì)自動(dòng)掃描被@SpringBootApplication注解的類(這里是SpringBootWebDemoApplication)的同級(jí)包以及子包中的Bean踢故。比如我們創(chuàng)建的DemoController,因?yàn)殚_(kāi)啟了SpringMVC自動(dòng)配置惹苗,同時(shí)又在對(duì)應(yīng)的路徑下殿较,所以該Controller會(huì)被自動(dòng)加載。比如我們這里指定掃描的包路徑如下:
@SpringBootApplication(scanBasePackages = {"com.temp.Controller"})
再次運(yùn)行程序桩蓉,發(fā)現(xiàn)原來(lái)的DemoController不能被訪問(wèn)了淋纲,而『com.temp.Controller』下的controller卻可以被訪問(wèn)。
那么問(wèn)題來(lái)了院究,SpringBoot到底為我們自動(dòng)配置了哪些功能呢洽瞬?
- 開(kāi)啟Debug模式,方式有多種:
- java -jar xx.jar --debug
- 在IDE中執(zhí)行Run時(shí)添加VM arguments:
-Ddebug
- 在項(xiàng)目resources下的application.properties文件中增加
debug=true
- Debug模式運(yùn)行程序业汰,打印信息中會(huì)顯示如下內(nèi)容
啟動(dòng)的自動(dòng)配置
未啟用的自動(dòng)配置
- 從打印結(jié)果中看到伙窃,每一個(gè)
*AutoConfiguration*
都對(duì)應(yīng)著一類功能的自動(dòng)配置類,比如HttpEncodingAutoConfiguration:
HttpEncodingAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.web.filter.CharacterEncodingFilter' (OnClassCondition)
- @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
- @ConditionalOnProperty (spring.http.encoding.enabled) matched (OnPropertyCondition)
- 開(kāi)啟的自動(dòng)配置中都會(huì)有
@ConditionalOnClass
样漆、@ConditionalOnWebApplication
等標(biāo)識(shí)为障,這是什么意思呢?為了弄清楚這個(gè)放祟,我們需要先來(lái)認(rèn)識(shí)一下@EnableAutoConfiguration
鳍怨;
@EnableAutoConfiguration
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector;
import org.springframework.context.annotation.Import;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
- 這里我們需要了解一下@Import注解中的EnableAutoConfigurationImportSelector
感興趣的可以看一下源碼,大體的功能就是掃描jar包里是否含有
META-INF/spring.factories
文件;
并在spring.factories中找到@EnableAutoConfiguration的全路徑名稱org.springframework.boot.autoconfigure.EnableAutoConfiguration這個(gè)key跪妥,該key對(duì)應(yīng)的value就是用于聲明都需要啟用哪些自動(dòng)配置類;
比如spring-boot-autoconfigure-1.4.2.RELEASE.jar中就有一個(gè)spring.factories鞋喇,可以看到org.springframework.boot.autoconfigure.EnableAutoConfiguration參數(shù)中列出了自動(dòng)配置類列表,而HttpEncodingAutoConfiguration這個(gè)自動(dòng)配置類就是其聲明的;
HttpEncodingAutoConfiguration
- 先看下源碼
@Configuration
@EnableConfigurationProperties({HttpEncodingProperties.class})
@ConditionalOnWebApplication
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
private final HttpEncodingProperties properties;
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean({CharacterEncodingFilter.class})
public CharacterEncodingFilter characterEncodingFilter() {
OrderedCharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}
//.......省略以下........
}
- 熟悉JavaConfig的都會(huì)明白眉撵,這就是一個(gè)配置類
@Configuration
侦香,并且通過(guò)@Bean
注冊(cè)了一個(gè)CharacterEncodingFilter
;
但是還有一些注解,是什么意思呢执桌,我們分別說(shuō)明:
- @EnableConfigurationProperties:開(kāi)啟屬性注入
本例中表示HttpEncodingProperties是屬性類鄙皇,并使用@Autowired自動(dòng)注入;
屬性類實(shí)際上是一個(gè)是注解了@ConfigurationProperties
的JavaBean仰挣,SpringBoot將屬性文件(application.properties)中的鍵值對(duì)與JavaBean的屬性建立起一一對(duì)應(yīng)關(guān)系:
@ConfigurationProperties(
prefix = "spring.http.encoding" //屬性值的前綴
)
/*
舉例:application.properties中設(shè)置如下屬性
spring.http.encoding.charset=UTF-8
spring.http.encoding.force=true
*/
public class HttpEncodingProperties {
private Charset charset;
private Boolean force;
//....屬性聲明及set伴逸、get方法........
}
所有@ConditionalOn開(kāi)頭的注解都是用于進(jìn)行條件判斷的
- @ConditionalOnWebApplication:當(dāng)前項(xiàng)目是web項(xiàng)目的條件下才加載當(dāng)前配置類
- @ConditionalOnClass:當(dāng)類路徑下有指定的類的條件下才加載當(dāng)前配置類
//本例表示,當(dāng)前類路徑(含jar)下必須存在CharacterEncodingFilter
@ConditionalOnClass({CharacterEncodingFilter.class})
- @ConditionalOnProperty:當(dāng)指定的屬性等于指定的值的情況下加載當(dāng)前配置類
// spring.http.encoding=enabled
// matchIfMissing = true表示如果沒(méi)有在application.properties設(shè)置該屬性膘壶,則默認(rèn)為條件符合
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
- @ConditionalOnMissingBean:當(dāng)前容器里沒(méi)有指定的Bean的情況下
// 如果當(dāng)前容器中找不到CharacterEncodingFilter實(shí)例错蝴,則創(chuàng)建當(dāng)前的Bean
@ConditionalOnMissingBean({CharacterEncodingFilter.class})
通過(guò)上面的分析洲愤,應(yīng)該可以明白SpringBoot是如何做到自動(dòng)配置的,簡(jiǎn)單總結(jié)如下:
- @SpringBootConfiguration實(shí)際上就是@Configuration顷锰,說(shuō)明這是一個(gè)JavaConfig
- @EnableAutoConfiguration負(fù)責(zé)掃描jar包中的
META-INF/spring.factories
來(lái)找到要初始化的各種AutoConfiguration類 - 各種@Conditional注解決定哪些Bean可以被容器初始化
- 如果希望進(jìn)一步了解SpringBoot的自動(dòng)配置柬赐,建議查看每一個(gè)AutoConfiguration類的源碼
除了上面介紹的,@Conditional注解還有如下形式
- @ConditionalOnExpression:基于SpEL表達(dá)式作為條件判斷
- @ConditionalOnJava:基于JAVA版本作為判斷條件
- @ConditionalOnJndi:在JNDI存在的條件下查找指定的位置
- @ConditionalOnMissingClass:當(dāng)前類路徑下沒(méi)有指定的類的條件下
- @ConditionalOnNotWebApplication:當(dāng)前項(xiàng)目不是web項(xiàng)目的條件下
- @ConditionalOnResource:類路徑下是否有指定的值
- @ConditionalOnSingleCandidate:當(dāng)指定的Bean在容器中只有一個(gè)的情況下
如果我們希望自己創(chuàng)建一個(gè)自動(dòng)配置類(AutoConfiguration)官紫,則只需要在我們自己創(chuàng)建的JavaConfig中加上@ConditionalOn注解肛宋,并且在類路徑下創(chuàng)建META-INF/spring.factories
,加入?yún)?shù)org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxxxAutoConfiguration
SpringBoot的配置文件
- SpringBoot支持常規(guī)的properties配置文件(application.properties)束世,還支持yaml語(yǔ)言的配置文件(application.yml)
- SpringBoot會(huì)從classpath下的/config目錄或者classpath的根目錄查找application.properties或application.yml
- 如果要修改SpringBoot自動(dòng)配置中默認(rèn)配置酝陈,可以通過(guò)在配置文件中配置相應(yīng)的參數(shù)即可
- 比如,項(xiàng)目啟動(dòng)時(shí)毁涉,tomcat默認(rèn)的端口號(hào)是『8080』沉帮,訪問(wèn)路徑是『/』,修改如下:
- application.properties
server.port=8081
server.context-path=/demo
- application.yml
server:
port: 8081
context-path: /demo
- IntelliJ IDEA支持對(duì)properties和yml的代碼提示功能贫堰,編輯起來(lái)還是很方便的穆壕,不需要特別記住這些屬性名稱
- SpringBoot默認(rèn)使用priperites進(jìn)行配置
SpringBoot的屬性可以通過(guò)多種方式指定,配置文件只是其中一種方式其屏,常用的方式還有如下幾種喇勋,按加載的優(yōu)先級(jí)列出:
命令行參數(shù):
java -jar xx.jar --server.port=8081 --server.context-path=/demo
操作系統(tǒng)環(huán)境變量:有些OS不支持使用.這種名字,如server.port漫玄,可以使用SERVER_PORT來(lái)配置茄蚯。
項(xiàng)目中的配置文件:application.properties或者application.yml
項(xiàng)目依賴jar包中的配置文件:application.properties或者application.yml
關(guān)于SpringBoot支持的配置屬性可以查看官網(wǎng)地址1.4.2.RELEASE
Profile配置
- 不同的環(huán)境可以使用不同的配置文件,application-{profile}.properties睦优,比如
開(kāi)發(fā):application-rnd.properties
測(cè)試:application-release.properties
驗(yàn)證:application-verify.properties
生產(chǎn):application-prod.properties
- 通過(guò)在application.properties(項(xiàng)目中必須包含該文件)中設(shè)置
spring.profiles.active=prod
來(lái)指定啟用哪一個(gè)Profile渗常。
關(guān)于屬性配置還想多說(shuō)的一些內(nèi)容
- application.properties也可以配置自定義屬性:my.name=hanqf
- 通過(guò)
@Value
將屬性注入Bean屬性
@Value("${my.name}")
private String myName;
- 通過(guò)
@ConfigurationProperties
將屬性注入Bean對(duì)象
使用prefix
my.name=hanqf
my.servers[0]=rnd.hanqf.com
my.servers[1]=release.hanqf.com
@ConfigurationProperties(prefix="my")
public class Config {
private String name;
private List<String> servers = new ArrayList<String>();//list需要初始化
//....set and get method
}
不使用prefix
name=hanqf
jdbc.username=root
jdbc.password=root
@ConfigurationProperties
public class Config {
private String name;
private Jdbc jdbc;
class Jdbc {
private String username;
private String password;
//....set and get method
}
//....set and get method
}
- 屬性占位符
app.name=MyApp
app.description=${app.name} is a Spring Boot application
server.port=${port:8080} # 如果沒(méi)有設(shè)置port,則使用默認(rèn)值8080
- 屬性名匹配規(guī)則
@ConfigurationProperties(prefix="person")
public class Config {
private String firstName;
//....set and get method
}
firstName
可以使用的屬性名如下:
person.firstName汗盘,標(biāo)準(zhǔn)的駝峰式命名
person.first-name皱碘,虛線(-)分割方式,推薦在.properties和.yml配置文件中使用
PERSON_FIRST_NAME隐孽,大寫(xiě)下劃線形式癌椿,建議在系統(tǒng)環(huán)境變量中使用
日志配置
- Spring Boot默認(rèn)使用Logback作為日志框架,這是推薦的方式菱阵,如果希望修改為熟悉的log4j可以看下文
創(chuàng)建項(xiàng)目時(shí)我們引入了
spring-boot-starter-web
踢俄,其依賴spring-boot-starter
,spring-boot-starter
又依賴于spring-boot-starter-logging
晴及,該依賴內(nèi)容就是Spring Boot默認(rèn)的日志框架Logback
Logback相關(guān)設(shè)置都办,可以在application.properties
中進(jìn)行如下配置:
# 日志文件路徑
logging.file=D:/my_log.log
# 配置日志打印級(jí)別
logging.level.org.springframework=INFO
當(dāng)然,也可以直接將自己的
logback.xml
放到項(xiàng)目根路徑下
- 修改為log4j框架
pom中排除對(duì)spring-boot-starter-logging
的依賴,并加入對(duì)spring-boot-starter-log4j
的依賴
目前maven中央倉(cāng)庫(kù)的最新版本是1.3.8.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
項(xiàng)目根路徑下添加log4j.properties
- 修改為log4j2框架
與log4j類似琳钉,修改pom势木,增加spring-boot-starter-log4j2
依賴
目前maven中央倉(cāng)庫(kù)的最新版本是1.4.2.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
項(xiàng)目根路徑下添加log4j2.xml
說(shuō)明
這里需要說(shuō)明一個(gè)問(wèn)題,如果切換為其它log框架歌懒,debug=true
將會(huì)失效啦桌,需要在各自的log配置文件中聲明,比如log4j需要添加log4j.logger.org.springframework.boot=debug
修改內(nèi)置Tomcat為Jetty
- 修改pom及皂,去除
spring-boot-starter-tomcat
的依賴甫男,增加spring-boot-starter-jetty
依賴
目前maven中央倉(cāng)庫(kù)的最新版本是1.4.2.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
-
application.properties
中的屬性配置與tomcat一致
修改內(nèi)置Tomcat為Undertow容器
- 修改pom,去除
spring-boot-starter-tomcat
的依賴验烧,增加spring-boot-starter-undertow
依賴
目前maven中央倉(cāng)庫(kù)的最新版本是1.4.2.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
-
application.properties
中的屬性配置與tomcat一致
單元測(cè)試
- 創(chuàng)建一個(gè)單元測(cè)試的抽象父類查剖,用于初始化必要的對(duì)象
package com.common;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringRunner.class)
//1.4.2.RELEASE中不再需要@SpringApplicationConfiguration和@WebAppConfiguration
@SpringBootTest
public abstract class SpringBootTestParent {
public MockMvc mockMvc;
@Autowired
WebApplicationContext webApplicationContext;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
- 繼承抽象父類,并實(shí)現(xiàn)測(cè)試邏輯
public class SpringBootWebDemoApplicationTests extends SpringBootTestParent{
@Autowired
DemoService demoService;
@Test
public void content(){
String content = "456";
System.out.println(demoService.printContent(content));
Assert.assertEquals(content,demoService.printContent(content));
}
@Test
public void DemoControllerContent(){
String uri = "/content/123";
MvcResult mvcResult;
try {
mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(uri)).andReturn();
System.out.println(mvcResult.getResponse().getStatus() + "##" + mvcResult.getResponse().getContentAsString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用war包的形式運(yùn)行項(xiàng)目
上面我們介紹了SpringBoot通過(guò)jar的形式運(yùn)行項(xiàng)目的方法噪窘,這也是SpringBoot推薦的方式,因其內(nèi)置Servlet容器效扫,所以發(fā)布和部署都非常方便倔监,但是某些情況下(比如使用JSP作為VIEW層,內(nèi)置容器的形式并不能支持)菌仁,我們希望將web項(xiàng)目部署到自己的容器中浩习,這時(shí)候就需要將SpringBoot項(xiàng)目打成war包部署,有兩種方式:
1.創(chuàng)建項(xiàng)目時(shí)打包方式選擇:war
war項(xiàng)目目錄結(jié)構(gòu)
2.將原打包方式為jar的項(xiàng)目修改為war形式
與war項(xiàng)目對(duì)比發(fā)現(xiàn)济丘,通過(guò)修改如下內(nèi)容谱秽,可以將jar項(xiàng)目修改為war項(xiàng)目
2.1 pom中將<packaging>jar</packaging>
==><packaging>war</packaging>
2.2 pom中添加tomcat依賴,顯示聲明scope為provided摹迷,這樣打包時(shí)就不會(huì)將tomcat的jar包打到war中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
2.3 創(chuàng)建ServletInitializer類
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DemoWarApplication.class);
}
}
說(shuō)明
- Servlet3.0規(guī)范疟赊,支持將web.xml相關(guān)配置也硬編碼到代碼中,并由
javax.servlet.ServletContainerInitializer
的實(shí)現(xiàn)類負(fù)責(zé)在容器啟動(dòng)時(shí)進(jìn)行加載 - spring提供了一個(gè)實(shí)現(xiàn)類
org.springframework.web.SpringServletContainerInitializer
,
該類會(huì)調(diào)用所有org.springframework.web.WebApplicationInitializer
的實(shí)現(xiàn)類的onStartup(ServletContext servletContext)方法峡碉,從而將相關(guān)的容器組件注冊(cè)到容器近哟; - SpringBootServletInitializer就是WebApplicationInitializer的實(shí)現(xiàn)類;
- 我之前寫(xiě)過(guò)一篇SpringMVC4零配置的文章鲫寄,對(duì)零配置感興趣的同學(xué)可以參考吉执。