Spring Boot學(xué)習(xí)筆記01--基本介紹

摘要

看完本文你將掌握如下知識(shí)點(diǎn):

  1. 如何搭建一個(gè)SpringBoot項(xiàng)目
  2. SpringBoot自動(dòng)配置原理
  3. SpringBoot屬性配置方法
  4. 修改默認(rèn)的Logback日志為log4j和log4j2的方法
  5. 修改默認(rèn)的內(nèi)置tomcat容器為Jetty容器和Undertow容器的方法
  6. SpringBoot單元測(cè)試方法
  7. 使用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)目

  1. 新建Spring Initializr項(xiàng)目


說(shuō)明:Spring Boot要求JDK1.6+

  1. 填寫(xiě)項(xiàng)目信息妇垢,構(gòu)建工具使用maven


  2. 選擇項(xiàng)目使用的依賴,這里我們只需要勾選web


  1. Spring Boot當(dāng)前最新的穩(wěn)定版是1.4.2创橄;
  2. 所有依賴可以在創(chuàng)建時(shí)勾選圃酵,也可以在創(chuàng)建后手工將依賴添加到pom中,如果對(duì)依賴比較熟悉豁状,推薦手工添加,這樣可以加快創(chuàng)建項(xiàng)目的時(shí)間;
  1. 填寫(xiě)項(xiàng)目名稱矿卑,點(diǎn)擊Finish


  2. 新建的項(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)目

  1. maven運(yùn)行:mvn spring-boot:run娘荡;
  2. main函數(shù)運(yùn)行:右鍵單擊SpringBootWebDemoApplication,選擇『Run 或者 Debug』;
  3. 推薦安裝JRebel插件庞溜,支持熱部署外构;
  4. 當(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!";
    }
}

一切似乎就是那么美好绿店,我們什么都沒(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é)如下:

  1. @SpringBootConfiguration實(shí)際上就是@Configuration顷锰,說(shuō)明這是一個(gè)JavaConfig
  2. @EnableAutoConfiguration負(fù)責(zé)掃描jar包中的META-INF/spring.factories來(lái)找到要初始化的各種AutoConfiguration
  3. 各種@Conditional注解決定哪些Bean可以被容器初始化
  4. 如果希望進(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-starterspring-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é)可以參考吉执。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市地来,隨后出現(xiàn)的幾起案子戳玫,更是在濱河造成了極大的恐慌,老刑警劉巖未斑,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咕宿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)荠列,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)类浪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人肌似,你說(shuō)我怎么就攤上這事费就。” “怎么了川队?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵力细,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我固额,道長(zhǎng)眠蚂,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任斗躏,我火速辦了婚禮逝慧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘啄糙。我一直安慰自己笛臣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布隧饼。 她就那樣靜靜地躺著沈堡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪燕雁。 梳的紋絲不亂的頭發(fā)上诞丽,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音拐格,去河邊找鬼僧免。 笑死,一個(gè)胖子當(dāng)著我的面吹牛捏浊,可吹牛的內(nèi)容都是我干的猬膨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼呛伴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼勃痴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起热康,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤沛申,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后姐军,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體铁材,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡尖淘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了著觉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片村生。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖饼丘,靈堂內(nèi)的尸體忽然破棺而出趁桃,到底是詐尸還是另有隱情,我是刑警寧澤肄鸽,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布卫病,位于F島的核電站,受9級(jí)特大地震影響典徘,放射性物質(zhì)發(fā)生泄漏蟀苛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一逮诲、第九天 我趴在偏房一處隱蔽的房頂上張望帜平。 院中可真熱鬧,春花似錦梅鹦、人聲如沸罕模。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蒿讥,卻和暖如春蝶念,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芋绸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工媒殉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人摔敛。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓廷蓉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親马昙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子桃犬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容