1. 程式人生 > >超詳細的Spring Boot入門筆記

超詳細的Spring Boot入門筆記

1. Spring Boot 入門
Spring Boot是Spring社群較新的一個專案。該專案的目的是幫助開發者更容易的建立基於Spring的應用程式和服務,讓更多人的人更快的對Spring進行入門體驗,讓Java開發也能夠實現Ruby on Rails那樣的生產效率。為Spring生態系統提供了一種固定的、約定優於配置風格的框架。
Spring Boot具有如下特性:

  • 為基於Spring的開發提供更快的入門體驗

  • 開箱即用,沒有程式碼生成,也無需XML配置。同時也可以修改預設值來滿足特定的需求。

  • 提供了一些大型專案中常見的非功能性特性,如嵌入式伺服器、安全、指標,健康檢測、外部配置等。

  • Spring Boot並不是對Spring功能上的增強,而是提供了一種快速使用Spring的方式。

1.1 簡單例子
首先建立一個一般的Maven專案,有一個pom.xml和基本的src/main/java結構。

1.1.1 pom.xml 檔案

<projectxmlns="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.nes.spring.boot</groupId> <artifactId>SpringBootDemo1</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId
>
<version>1.3.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <!-- Compile --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <!-- spring boot mavenplugin --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.5.RELEASE</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>

1.1.2 對pom的說明
首先是增加了,增加父pom比較簡單,而且spring-boot-starter-parent包含了大量配置好的依賴管理,在自己專案新增這些依賴的時候不需要寫版本號。
使用父pom雖然簡單,但是有些情況我們已經有父pom,不能直接增加時,可以通過如下方式:

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.2.3.RELEASE</version>
            <type>pom</type>
            <scope>import</scope><!—這個地方-->
        </dependency>
    </dependencies>
</dependencyManagement>

1.1.3 關於java.version屬性
上面pom.xml雖然沒有出現這個屬性,這裡要特別提醒。
Spring預設使用jdk1.6,如果你想使用jdk1.8,你需要在pom.xml的屬性裡面新增java.version,如下:

<properties>
    <java.version>1.8</java.version>
</properties>

1.1.4 新增spring-boot-starter-web依賴
Spring通過新增spring-boot-starter-*這樣的依賴就能支援具體的某個功能。
我們這個示例最終是要實現web功能,所以新增的是這個依賴。
更完整的功能列表可以檢視:Using-boot-starter-poms

1.1.4 新增spring-boot-maven-plugin外掛
該外掛支援多種功能,常用的有兩種,第一種是打包專案為可執行的jar包。
在專案根目錄下執行mvn package將會生成一個可執行的jar包,jar包中包含了所有依賴的jar包,只需要這一個jar包就可以執行程式,使用起來很方便。該命令執行後還會保留一個XXX.jar.original的jar包,包含了專案中單獨的部分。
生成這個可執行的jar包後,在命令列執行java -jar xxxx.jar即可啟動專案。
另外一個命令就是mvn spring-boot:run,可以直接使用tomcat(預設)啟動專案。
在我們開發過程中,我們需要經常修改,為了避免重複啟動專案,我們可以啟用熱部署。

1.1.6 spring-loaded熱部署
Spring-Loaded專案提供了強大的熱部署功能,新增/刪除/修改方法/欄位/介面/列舉等程式碼的時候都可以熱部署,速度很快,很方便。
想在Spring Boot中使用該功能非常簡單,就是在spring-boot-maven-plugin外掛下面新增依賴:

<!--  支援熱部署 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>springloaded</artifactId>
    <version>1.2.5.RELEASE</version>
</dependency>

新增以後,通過mvn spring-boot:run啟動就支援熱部署了。
注意:使用熱部署的時候,需要IDE編譯類後才能生效,你可以開啟自動編譯功能,這樣在你儲存修改的時候,類就自動重新載入了。

1.2 建立一個應用類
我們建立一個Application類:

@RestController
@EnableAutoConfiguration
public class Application {

@RequestMapping("/") String home() {
    return"Hello World!";
    }
@RequestMapping("/now") String hehe() {
    return"現在時間:" + (new Date()).toLocaleString();
    }
public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
    }
}

1.2.1 注意
Spring Boot建議將我們main方法所在的這個主要的配置類配置在根包名下。

com
 +- example
     +- myproject
         +- Application.java
         +- domain
|   +- Customer.java
|   +- CustomerRepository.java
         +- service
|   +- CustomerService.java
         +- web
             +- CustomerController.java

在Application.java中有main方法。
因為預設和包有關的註解,預設包名都是當前類所在的包,例如@ComponentScan, @EntityScan, @SpringBootApplication註解。(都是安當前Application.java所在包作為Scan掃描)

1.2.2 @RestController
因為我們例子是寫一個web應用,因此寫的這個註解,這個註解相當於同時新增@Controller和@ResponseBody註解。

1.2.3 @EnableAutoConfiguration
Spring Boot建議只有一個帶有該註解的類。
@EnableAutoConfiguration作用:Spring Boot會自動根據你jar包的依賴來自動配置專案。
例如當你專案下面有HSQLDB的依賴時,Spring Boot會建立預設的記憶體資料庫的資料來源DataSource,如果你自己建立了DataSource,Spring Boot就不會建立預設的DataSource。

如果你不想讓Spring Boot自動建立,你可以配置註解的exclude屬性,例如:

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
publicclassMyConfiguration {
}

1.2.4 @SpringBootApplication
由於大量專案都會在主要的配置類上新增
@Configuration,@EnableAutoConfiguration,@ComponentScan三個註解。
因此Spring Boot提供了@SpringBootApplication註解,該註解可以替代上面三個註解(使用Spring註解繼承實現)。

1.2.5 啟動專案SpringApplication.run
啟動Spring Boot專案最簡單的方法就是執行下面的方法:
SpringApplication.run(Application.class, args);
該方法返回一個ApplicationContext物件,使用註解的時候返回的具體型別是AnnotationConfigApplicationContext或AnnotationConfigEmbeddedWebApplicationContext,當支援web的時候是第二個。

除了上面這種方法外,還可以用下面的方法:

SpringApplication application = new SpringApplication(Application.class);
application.run(args);

SpringApplication包含了一些其他可以配置的方法,如果你想做一些配置,可以用這種方式。

除了上面這種直接的方法外,還可以使用SpringApplicationBuilder:

new SpringApplicationBuilder()
        .showBanner(false)
        .sources(Application.class)
        .run(args);

當使用SpringMVC的時候由於需要使用子容器,就需要用到SpringApplicationBuilder,該類有一個child(xxx…)方法可以新增子容器。

1.3 執行
在IDE中直接直接執行main方法,然後訪問http://localhost:8080即可。
另外還可以用上面提到的mvn,可以打包為可執行jar包,然後執行java -jar xxx.jar。
或者執行mvn spring-boot:run執行專案。

2. Spring Boot 屬性配置和使用
Spring Boot 允許通過外部配置讓你在不同的環境使用同一應用程式的程式碼,簡單說就是可以通過配置檔案來注入屬性或者修改預設的配置。

2.1 Spring Boot 支援多種外部配置方式
這些方式優先順序如下:

  1. 命令列引數
  2. 來自java:comp/env的JNDI屬性
  3. Java系統屬性(System.getProperties())
  4. 作業系統環境變數
  5. RandomValuePropertySource配置的random.*屬性值
  6. jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置檔案
  7. jar包內部的application-{profile}.properties或application.yml(帶spring.profile)配置檔案
  8. jar包外部的application.properties或application.yml(不帶spring.profile)配置檔案
  9. jar包內部的application.properties或application.yml(不帶spring.profile)配置檔案
  10. @Configuration註解類上的@PropertySource
  11. 通過SpringApplication.setDefaultProperties指定的預設屬性

2.1.1 命令列引數
通過java -jar app.jar –name=”Spring” –server.port=9090方式來傳遞引數。
引數用–xxx=xxx的形式傳遞。
可以使用的引數可以是我們自己定義的,也可以是Spring Boot中預設的引數。
很多人可能會關心如web埠如何配置這樣的問題,這些都是Spring Boot中提供的引數,部分可用引數如下:

# LOGGING
logging.path=/var/logs
logging.file=myapp.log
logging.config= # location of config file (default classpath:logback.xml for logback)
logging.level.*= # levels for loggers, e.g. "logging.level.org.springframework=DEBUG" (TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF)

# EMBEDDED SERVER CONFIGURATION (ServerProperties)
server.port=8080
server.address= # bind to a specific NIC
server.session-timeout= # session timeout in seconds
server.context-parameters.*= # Servlet context init parameters, e.g. server.context-parameters.a=alpha
server.context-path= # the context path, defaults to '/'
server.servlet-path= # the servlet path, defaults to '/'

更多常見的應用屬性請瀏覽這裡
注意:命令列引數在app.jar的後面!
可以通過SpringApplication.setAddCommandLineProperties(false)禁用命令列配置。

2.1.2 Java系統屬性
注意Java系統屬性位置java -Dname=”isea533” -jar app.jar,可以配置的屬性都是一樣的,優先順序不同。
例如java -Dname=”isea533” -jar app.jar –name=”Spring!”中name值為Spring!

2.1.3 作業系統環境變數
配置過JAVA_HOME的應該都瞭解這一個。
這裡需要注意的地方,有些OS可以不支援使用.這種名字,如server.port,這種情況可以使用SERVER_PORT來配置。

2.1.4 RandomValuePropertySource
系統中用到隨機數的地方,例如:
my.secret=random.valuemy.number={random.int}
my.bignumber=random.longmy.number.less.than.ten={random.int(10)}
my.number.in.range=${random.int[1024,65536]}
random.int*支援value引數和,max引數,當提供max引數的時候,value就是最小值。

2.1.5 應用配置檔案(.properties或.yml)
在配置檔案中直接寫:

name=Isea533
server.port=8080

.yml格式的配置檔案如:

name: Isea533
  server:
    port: 8080

當有字首的情況下,使用.yml格式的配置檔案更簡單。關於.yml配置檔案用法請看這裡
注意:使用.yml時,屬性名的值和冒號中間必須有空格,如name: Isea533正確,name:Isea533就是錯的。

2.1.5.1屬性配置檔案的位置
spring會從classpath下的/config目錄或者classpath的根目錄查詢application.properties或application.yml。
/config優先於classpath根目錄

2.1.6 @PropertySource
這個註解可以指定具體的屬性配置檔案,優先順序比較低。

2.1.7 SpringApplication.setDefaultProperties
例如:

SpringApplication application = new SpringApplication(Application.class);
Map<String, Object>defaultMap = new HashMap<String, Object>();
defaultMap.put("name", "Isea-Blog");
//還可以是Properties物件
application.setDefaultProperties(defaultMap);
application.run(args);
2.2 應用(使用)屬性
2.2.1 @Value(“${xxx}”)
這種方式是最簡單的,通過@Value註解可以將屬性值注入進來。
2.2.2 @ConfigurationProperties
Spring Boot 可以方便的將屬性注入到一個配置物件中。例如:
my.name=Isea533
my.port=8080
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
對應物件:
@ConfigurationProperties(prefix="my")
publicclassConfig {
private String name;
private Integer port;
private List<String> servers = newArrayList<String>();
public String geName(){
returnthis.name;
    }
public Integer gePort(){
returnthis.port;
    }
public List<String>getServers() {
returnthis.servers;
    }
}

Spring Boot 會自動將prefix=”my”字首為my的屬性注入進來。
Spring Boot 會自動轉換型別,當使用List的時候需要注意在配置中對List進行初始化!
Spring Boot 還支援巢狀屬性注入,例如:

name=isea533
jdbc.username=root
jdbc.password=root
...

對應的配置類:

@ConfigurationProperties
publicclassConfig {
private String name;
privateJdbcjdbc;
    class Jdbc {
private String username;
private String password;
//getter...
    }
public Integer gePort(){
returnthis.port;
    }
publicJdbcgetJdbc() {
returnthis.jdbc;
    }
}

jdbc開頭的屬性都會注入到Jdbc物件中。

2.2.3 在@Bean方法上使用@ConfigurationProperties
例如:

@ConfigurationProperties(prefix = "foo")
@Bean
publicFooComponentfooComponent() {
    ...
}

Spring Boot 會將foo開頭的屬性按照名字匹配注入到FooComponent物件中。

2.2.4 屬性佔位符
例如:

app.name=MyApp
app.description=${app.name} is a Spring Boot application
可以在配置檔案中引用前面配置過的屬性(優先順序前面配置過的這裡都能用)。
通過如${app.name:預設名稱}方法還可以設定預設值,當找不到引用的屬性時,會使用預設的屬性。
由於${}方式會被Maven處理。如果你pom繼承的spring-boot-starter-parentSpring Boot 已經將maven-resources-plugins預設的${}方式改為了@ @方式,例如@[email protected]。
如果你是引入的Spring Boot,你可以修改使用其他的分隔符

2.2.5 通過屬性佔位符還能縮短命令引數
例如修改web預設埠需要使用–server.port=9090方式,如果在配置中寫上:

server.port=${port:8080}

那麼就可以使用更短的–port=9090,當不提供該引數的時候使用預設值8080。

2.2.6 屬性名匹配規則
例如有如下配置物件:

@Component
@ConfigurationProperties(prefix="person")
publicclassConnectionSettings {
private String firstName;
}

firstName可以使用的屬性名如下:
person.firstName,標準的駝峰式命名
person.first-name,虛線(-)分割方式,推薦在.properties和.yml配置檔案中使用
PERSON_FIRST_NAME,大寫下劃線形式,建議在系統環境變數中使用

2.2.7 屬性驗證
可以使用JSR-303註解進行驗證,例如:

@Component
@ConfigurationProperties(prefix="connection")
publicclassConnectionSettings {
@NotNull
privateInetAddressremoteAddress;
// ... getters and setters
}

2.3 最後
以上是Spring Boot 屬性配置和使用的內容,有些不全面的地方或者讀者有更多疑問,可以檢視Spring Boot完整文件 或 Externalized Configuration。

3. Spring Boot 整合MyBatis

3.1. Spring Boot 整合druid
druid有很多個配置選項,使用Spring Boot 的配置檔案可以方便的配置druid。
在application.yml配置檔案中寫上:

spring:
datasource:
        name: test
        url: jdbc:mysql://192.168.16.137:3306/test
        username: root
        password:
# 使用druid資料來源
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        filters: stat
        maxActive: 20
        initialSize: 1
        maxWait: 60000
        minIdle: 1
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxOpenPreparedStatements: 20

這裡通過type: com.alibaba.druid.pool.DruidDataSource配置即可!

3.2. Spring Boot 整合MyBatis
Spring Boot 整合MyBatis有兩種方式,一種簡單的方式就是使用MyBatis官方提供的:
mybatis-spring-boot-starter
另外一種方式就是仍然用類似mybatis-spring的配置方式,這種方式需要自己寫一些程式碼,但是可以很方便的控制MyBatis的各項配置。

3.2.1. mybatis-spring-boot-starter方式
在pom.xml中新增依賴:

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>

mybatis-spring-boot-starter依賴樹如下:

這裡寫圖片描述

其中mybatis使用的3.3.0版本,可以通過:

mybatis: 
mapperLocations: classpath:mapper/*.xml
typeAliasesPackage: tk.mapper.model

除了上面常見的兩項配置,還有:
mybatis.config:mybatis-config.xml配置檔案的路徑
mybatis.typeHandlersPackage:掃描typeHandlers的包
mybatis.checkConfigLocation:檢查配置檔案是否存在
mybatis.executorType:設定執行模式(SIMPLE, REUSE, BATCH),預設為SIMPLE

3.2.2 mybatis-spring方式
這種方式和平常的用法比較接近。需要新增mybatis依賴和mybatis-spring依賴。
然後建立一個MyBatisConfig配置類:

/**
 * MyBatis基礎配置
 *
 * @authorliuzh
 * @since 2015-12-19 10:11
 */
@Configuration
@EnableTransactionManagement
publicclassMyBatisConfigimplementsTransactionManagementConfigurer {
@Autowired
DataSourcedataSource;

@Bean(name = "sqlSessionFactory")
publicSqlSessionFactorysqlSessionFactoryBean() {
SqlSessionFactoryBean bean = newSqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("tk.mybatis.springboot.model");

//分頁外掛
PageHelperpageHelper = newPageHelper();
        Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);

//新增外掛
bean.setPlugins(new Interceptor[]{pageHelper});

//新增XML目錄
ResourcePatternResolver resolver = newPathMatchingResourcePatternResolver();
try {
            bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
returnbean.getObject();
        } catch (Exception e) {
e.printStackTrace();
thrownewRuntimeException(e);
        }
    }
@Bean
publicSqlSessionTemplatesqlSessionTemplate(SqlSessionFactorysqlSessionFactory) {
returnnewSqlSessionTemplate(sqlSessionFactory);
    }

@Bean
@Override
publicPlatformTransactionManagerannotationDrivenTransactionManager() {
returnnewDataSourceTransactionManager(dataSource);
    }
}

上面程式碼建立了一個SqlSessionFactory和一個SqlSessionTemplate,為了支援註解事務,增加了@EnableTransactionManagement註解,並且反回了一個PlatformTransactionManagerBean。
另外應該注意到這個配置中沒有MapperScannerConfigurer,如果我們想要掃描MyBatis的Mapper介面,我們就需要配置這個類,這個配置我們需要單獨放到一個類中。

/**
 * MyBatis掃描介面
 * 
 * @authorliuzh
 * @since 2015-12-19 14:46
 */
@Configuration
//注意,由於MapperScannerConfigurer執行的比較早,所以必須有下面的註解
@AutoConfigureAfter(MyBatisConfig.class)
publicclassMyBatisMapperScannerConfig {
@Bean
publicMapperScannerConfigurermapperScannerConfigurer() {
MapperScannerConfigurermapperScannerConfigurer = newMapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setBasePackage("tk.mybatis.springboot.mapper");
        //配置通用mappers
Propertiesproperties=newProperties();
properties.setProperty("mappers", "tk.mybatis.springboot.util.MyMapper");
properties.setProperty("notEmpty", "false");
properties.setProperty("IDENTITY", "MYSQL");
//這裡使用的通用Mapper的MapperScannerConfigurer,所有有下面這個方法
mapperScannerConfigurer.setProperties(properties);

returnmapperScannerConfigurer;
    }
}

這個配置一定要注意@AutoConfigureAfter(MyBatisConfig.class),必須有這個配置,否則會有異常。原因就是這個類執行的比較早,由於sqlSessionFactory還不存在,後續執行出錯。做好上面配置以後就可以使用MyBatis了。

3.3. 關於分頁外掛和通用Mapper整合
分頁外掛作為外掛的例子在上面程式碼中有。
通用Mapper配置實際就是配置MapperScannerConfigurer的時候使用tk.mybatis.spring.mapper.MapperScannerConfigurer即可,配置屬性使用Properties。

4. Spring Boot 靜態資源處理
Spring Boot 預設的處理方式就已經足夠了,預設情況下Spring Boot 使用WebMvcAutoConfiguration中配置的各種屬性。
建議使用Spring Boot 預設處理方式,需要自己配置的地方可以通過配置檔案修改。
但是如果你想完全控制Spring MVC,你可以在@Configuration註解的配置類上增加@EnableWebMvc,增加該註解以後WebMvcAutoConfiguration中配置就不會生效,你需要自己來配置需要的每一項。這種情況下的配置方法建議參考WebMvcAutoConfiguration類。
本文以下內容針對Spring Boot 預設的處理方式,部分配置通過在application.yml配置檔案中設定。

1.spring boot預設載入檔案的路徑是

/META-INF/resources/ 
/resources/ 
/static/ 
/public/
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {  
        "classpath:/META-INF/resources/", "classpath:/resources/",  
        "classpath:/static/", "classpath:/public/" };  

所有本地的靜態資源都配置在了classpath下面了, 而非在webapp下了

4.1. 配置資源對映
Spring Boot 預設配置的/對映到/static(或/public ,/resources,/META-INF/resources),/webjars/會對映到
classpath:/META-INF/resources/webjars/。
注意:上面的/static等目錄都是在classpath:下面。
如果你想增加如/mystatic/**對映到classpath:/mystatic/,你可以讓你的配置類繼承WebMvcConfigurerAdapter,然後重寫如下方法:

@Override
publicvoidaddResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/mystatic/**")
            .addResourceLocations("classpath:/mystatic/");
}

這種方式會在預設的基礎上增加/mystatic/**對映到classpath:/mystatic/,不會影響預設的方式,可以同時使用。
靜態資源對映還有一個配置選項,為了簡單這裡用.properties方式書寫:
spring.mvc.static-path-pattern=/** # Path pattern used forstatic resources.
這個配置會影響預設的/,例如修改為/static/後,只能對映如/static/js/sample.js這樣的請求(修改前是/js/sample.js)。這個配置只能寫一個值,不像大多數可以配置多個用逗號隔開的。

4.2. 使用注意
例如有如下目錄結構:

└─resources
│  application.yml
    │
    ├─static
│  ├─css
│  │index.css
    │  │
│  └─js
    │          index.js
    │
    └─templates
index.ftl

在index.ftl中該如何引用上面的靜態資源呢?
如下寫法:

<linkrel="stylesheet"type="text/css"href="/css/index.css">
<scripttype="text/javascript"src="/js/index.js"></script>

注意:預設配置的/**對映到/static(或/public ,/resources,/META-INF/resources)
當請求/css/index.css的時候,Spring MVC 會在/static/目錄下面找到。
如果配置為/static/css/index.css,那麼上面配置的幾個目錄下面都沒有/static目錄,因此會找不到資原始檔!
所以寫靜態資源位置的時候,不要帶上對映的目錄名(如/static/,/public/,/resources/,/META-INF/resources/)!

4.3. 使用WebJars
WebJars:http://www.webjars.org/
例如使用jquery,新增依賴:

<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.11.3</version>
</dependency>

然後可以如下使用:

<scripttype="text/javascript"
src="/webjars/jquery/1.11.3/jquery.js"></script>

你可能注意到href中的1.11.3版本號了,如果僅僅這麼使用,那麼當我們切換版本號的時候還要手動修改href,怪麻煩的,我們可以用如下方式解決。
先在pom.xml中新增依賴:

<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
</dependency>

增加一個WebJarController:

@Controller
publicclassWebJarController {
privatefinalWebJarAssetLocatorassetLocator = newWebJarAssetLocator();

@ResponseBody
@RequestMapping("/webjarslocator/{webjar}/**")
publicResponseEntitylocateWebjarAsset(@PathVariable String webjar, HttpServletRequest request) {
try {
            String mvcPrefix = "/webjarslocator/" + webjar + "/";
            String mvcPath = 
(String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
            String fullPath = 
assetLocator.getFullPath(webjar, mvcPath.substring(mvcPrefix.length()));
returnnewResponseEntity(newClassPathResource(fullPath), HttpStatus.OK);
        } catch (Exception e) {
returnnewResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
}

然後使用的時候按照如下方式:

<script
type="text/javascript"src="/webjarslocator/jquery/jquery.js"></script>

注意:這裡不需要在寫版本號了,但是注意寫url的時候,只是在原來url基礎上去掉了版本號,其他的都不能少!

4.4. 靜態資源版本管理
Spring MVC 提供了靜態資源版本對映的功能。
用途:當我們資源內容發生變化時,由於瀏覽器快取,使用者本地的靜態資源還是舊的資源,為了防止這種情況導致的問題,我們可能會手動在請求url的時候加個版本號或者其他方式。
版本號如:

<script
type="text/javascript"src="/js/sample.js?v=1.0.1"></script>

Spring MVC 提供的功能可以很容易的幫助我們解決類似問題。
Spring MVC 有兩種解決方式。
注意:下面的配置方式針對freemarker模板方式,其他的配置方式可以參考。

4.4.1. 資源名-md5 方式

<link rel="stylesheet"type="text/css"href="/css/index-2b371326aa93ce4b611853a309b69b29.css">

Spring 會自動讀取資源md5,然後新增到index.css的名字後面,因此當資源內容發生變化的時候,檔名發生變化,就會更新本地資源。
配置方式:
在application.properties中做如下配置:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

這樣配置後,所有/**請求的靜態資源都會被處理為上面例子的樣子。
到這兒還沒完,我們在寫資源url的時候還要特殊處理。
首先增加如下配置:

@ControllerAdvice
publicclassControllerConfig {
@Autowired
ResourceUrlProviderresourceUrlProvider;
@ModelAttribute("urls")
publicResourceUrlProviderurls() {
returnthis.resourceUrlProvider;
    }
}

然後在頁面寫的時候用下面的寫法:

<linkrel="stylesheet"type="text/css"href="${urls.getForLookupPath('/css/index.css')}">

使用urls.getForLookupPath(‘/css/index.css’)來得到處理後的資源名。

4.4.2. 版本號方式
在application.properties中做如下配置:

spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/**,/v1.0.0/**
spring.resources.chain.strategy.fixed.version=v1.0.0

這裡配置需要特別注意,將version的值配置在paths中。
在頁面寫的時候,寫法如下:

<script
type="text/javascript"src="${urls.getForLookupPath('/js/index.js')}"></script>

注意,這裡仍然使用了urls.getForLookupPath,urls配置方式見上一種方式。
在請求的實際頁面中,會顯示為:

<script
type="text/javascript"src="/v1.0.0/js/index.js"></script>

可以看到這裡的地址是/v1.0.0/js/index.js。

4.5. 靜態資源版本管理處理過程
在Freemarker模板首先會呼叫urls.getForLookupPath方法,返回一個/v1.0.0/js/index.js或/css/index-2b371326aa93ce4b611853a309b69b29.css。
這時頁面上的內容就是處理後的資源地址。這之後瀏覽器發起請求。
這裡分開說。

  • 第一種md5方式

請求/css/index-2b371326aa93ce4b611853a309b69b29.css,我們md5配置的paths=/**,所以Spring MVC 會嘗試url中是否包含-,如果包含會去掉後面這部分,然後去對映的目錄(如/static/)查詢/css/index.css檔案,如果能找到就返回。
第二種版本方式

  • 請求/v1.0.0/js/index.js。

如果我們paths中沒有配置/v1.0.0,那麼上面這個請求地址就不會按版本方式來處理,因此會找不到上面的資源。
如果配置了/v1.0.0,Spring 就會將/v1.0.0去掉再去找/js/index.js,最終會在/static/下面找到。