一、導(dǎo)覽
本文主要按以下模塊介紹spring Boot(1.4.2.RELEASE)提供的特性。
SpringApplication類
外部化配置
Profiles
日志
開發(fā)WEB應(yīng)用
Security
使用SQL
使用NoSQL
緩存
消息
發(fā)送郵件
JTA處理分布式事務(wù)
Spring Session
測試
Actuator
部署
二、SpringApplication類
在主類——即帶有@SpringBootApplication注解類,的main方法里調(diào)用SpringApplication.run(應(yīng)用的Configration配置類.class,參數(shù)列表) 會啟動spring應(yīng)用。默認(rèn)log級別是INFO,會顯示一些相關(guān)的啟動詳情,比如啟動應(yīng)用的用戶等。
- 使用SpringApplicationBuilder類可以創(chuàng)建分層的
ApplicationContext
new SpringApplicationBuilder()
.bannerMode(Banner.Mode.OFF)
.sources(Parent.class)
.child(Application.class)
.run(args);
- Application事件和監(jiān)聽器
除了常用的Spring framework事件,例如ContextRefreshedEvent等,SpringApplication也會發(fā)送一些其他的應(yīng)用事件。
一些事件在ApplicationContext被創(chuàng)建之前就被觸發(fā),因此無法將監(jiān)聽器注冊為bean來監(jiān)聽。但是可以使用SpringApplication.addListeners(…) 或SpringApplicationBuilder.listeners(…)來注冊監(jiān)聽器。也可以在META-INF/spring.factories文件定義監(jiān)聽器:
org.springframework.context.ApplicationListener=com.example.project.MyListener
應(yīng)用運(yùn)行時,應(yīng)用事件發(fā)送順序如下:
① 在監(jiān)聽器和初始化器被初始化之后,任何其他應(yīng)用之前,應(yīng)用剛開始運(yùn)行時會發(fā)送一個ApplicationStartedEvent。
② 在context被創(chuàng)建之前,context中要使用的Environment被知道時,一個ApplicationEnvironmentPreparedEvent被發(fā)送。
③ 在bean定義被加載之后,refresh啟動之前,一個ApplicationPreparedEvent被發(fā)送。
④ 在refresh以及任何相關(guān)的回調(diào)被處理之后,一個ApplicationReadyEvent被發(fā)送,表明應(yīng)用已準(zhǔn)備好服務(wù)requests。
⑤ 啟動時如果發(fā)生異常,一個ApplicationFailedEvent被發(fā)送。
web環(huán)境
SpringApplication會根據(jù)應(yīng)用是否為web來創(chuàng)建不同的ApplicationContext: AnnotationConfigApplicationContext或AnnotationConfigEmbeddedWebApplicationContext。
可以調(diào)用setWebEnvironment(boolean webEnvironment)復(fù)寫默認(rèn)實(shí)現(xiàn)(在junit測試時置為false最好),更可以使用setApplicationContextClass(…).完全控制ApplicationContext的創(chuàng)建。在SpringApplication.run完成前執(zhí)行特定代碼
使用ApplicationRunner或CommandLineRunner,并配合Order注解指定調(diào)用順序。
CommandLineRunner的run(String …args)方法直接訪問SpringApplication.run傳遞的參數(shù),ApplicationRunner的run方法則使用ApplicationArguments訪問參數(shù)。例如:
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
三、外部化配置
- 如何引用配置的屬性
可使用properties文件,YAML文件,環(huán)境變量,命令行參數(shù)(如 –name=”fuck”)來外部化配置。屬性值可以使用@Value注解直接注入到bean中,并通過Spring的Environment抽象或經(jīng)過@ ConfigurationProperties 注解綁定到結(jié)構(gòu)化對象來訪問。
示例:
YAML文件:
yml 屬性
或者等效的properties文件:
properties屬性
使用@Value注入單個屬性:
單個屬性
使用@ ConfigurationProperties注入屬性族:
屬性組
※ 注意里面使用了JSR-303注解來校驗(yàn)屬性值。
@ ConfigurationProperties還可以用到@Bean注解的方法上。
bean定義
- 屬性加載順序
Spring按照如下順序設(shè)置properties:
(一) 命令行參數(shù)。如:Java -jar app.jar –name=”Spring”
(二) SPRING_APPLICATION_JSON。如java -Dspring.application.json=’{“foo”:”bar”, “hehe”:”fuck”}’ -jar fuckapp.jar
(三) 來自于java:comp/env的JNDI屬性
(四) Java System properties (System.getProperties()).
(五) OS環(huán)境變量
(六) 只有在random.*里包含的屬性會產(chǎn)生一個RandomValuePropertySource
(七) jar包外部的,由profile指定的application properties文件(application-{profile}.properties或YAML文件)
(八) jar包內(nèi)部的,由profile指定的application properties文件(application-{profile}.properties或YAML文件)
(九) jar包外部的application properties(application.properties和YAML)。
(十) jar包內(nèi)部的application properties(application.properties和YAML)。
(十一) @Configuration注解類內(nèi)部的@PropertySource注解
(十二) 由SpringApplication.setDefaultProperties設(shè)置的默認(rèn)屬性
YAML是JSON的超集,非常適合定義層級化配置數(shù)據(jù)。引入SnakeYAML庫會使SpringApplication類自動支持YAML。使用spring-boot-starter會自動引入YAML。
四、Profiles
Spring Profiles提供了一種隔離應(yīng)用程序配置的方式,并讓這些配置只能在特定的環(huán)境下生效。
- 如何配置profile
任何@Component或@Configuration都能被@Profile標(biāo)記,從而限制加載它的時機(jī)。
例如:
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
- 如何在構(gòu)建時指定profile
以正常的Spring方式,你可以使用一個spring.profiles.active的Environment屬性來指定哪個配置生效。你可以使用平常的任
何方式來指定該屬性,例如,可以將它包含到你的application.properties中:
spring.profiles.active=dev,hsqldb
或使用命令行開關(guān):
--spring.profiles.active=dev,hsqldb
2.1 添加激活的配置(profiles)
spring.profiles.active屬性和其他屬性一樣都遵循上文中提到屬性加載規(guī)則,優(yōu)先級最高的PropertySource獲勝。也就是說,你可以在application.properties中指定生效的配置,然后在命令行中設(shè)置同名屬性的不同值來替換它們。
有些時候,將profile特定的屬性增加到active profile中,而不是直接替換會更有用。spring.profiles.include屬性就可以用來無條件增加active profiles。SpringApplication類也提供api設(shè)置額外的profile(setAdditionalProfiles())
例如,按照下面的配置:
--- my.property: fromyamlfile ---
spring.profiles: prod
spring.profiles.include: proddb,prodmq
如果應(yīng)用啟動時打開選項–spring.profiles.active=prod,則proddb和prodmq也會被激活。
2.2 編程方式設(shè)置profile
在調(diào)用SpringApplication.run之前調(diào)用SpringApplication.setAdditionalProfiles(…)即可。實(shí)現(xiàn)ConfigurableEnvironment接口也可行。
2.3 profile特定的配置文件
除了application.properties文件,profile特定的屬性也能通過application-{profile}.properties來定義。Spring boot提供了默認(rèn)的application-default.properties文件,在沒有定義任何profile時會加載。
profile特定的屬性從跟標(biāo)準(zhǔn)application.properties相同的路徑加載,并且特定profile文件會覆蓋默認(rèn)的配置。如果聲明了不止一個profile,則最后聲明的被采用。
2.4 屬性中的占位符(placeholders)
application.properties中的值會將由Environment過濾,所以你可以直接飲用之前定義的值:
app.name=MyApp
app.description=${app.name} is a Spring Boot application
五、日志
Spring Boot內(nèi)部日志使用Commons Logging,但是開發(fā)底層日志實(shí)現(xiàn)。會為Java Util Logging, Log4j, Log4j2和Logback提供默認(rèn)配置。不論哪種配置,loggers都被預(yù)配置為使用console輸出,并提供一個可選的文件輸出。
默認(rèn)情況下,如果是使用’Starter POMs’,Logback將被用作日志實(shí)現(xiàn)。
- Log 格式
Spring Boot默認(rèn)的log格式如下:
2016-07-14 17:27:33.212 INFO 13092 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3832 ms
2016-07-14 17:27:33.668 WARN 13092 --- [ost-startStop-1] .s.b.d.a.RemoteDevToolsAutoConfiguration : Listening for remote debug traffic on /.~spring-boot!/debug
1
2
3
1
2
3
顯示以下內(nèi)容:
日期和時間—毫秒精度,利于排序
Log級別—ERROR, WARN, INFO, DEBUG or TRACE.
PID.
一個— 分隔符,表明實(shí)際log消息的開始
線程名—方括號中顯示(控制臺輸出時可能會被省略)
Logger名—一般是類名的縮寫格式
log消息
- 控制臺輸出
默認(rèn),log信息被原樣輸出到控制臺,輸出ERROR, WARN, INFO級別??梢酝ㄟ^以下手段激活debug模式,輸出更多的信息:
在命令行使用 –debug 選項
在application.properties中添加debug=true
開啟debug模式后,一些核心的loggers(如嵌入的servlet容器,hibernate和Spring)被配置輸出更多的信息。
請注意
此處開啟的debug模式,并非將你應(yīng)用的日志級別修改為DEBUG級別。
Spring Boot輸出日志到控制臺時,會檢測console是否支持ansi,如果支持,會顯示彩色的日志。可以停止這種檢測,或更改檢測策略:
將 spring.output.ansi.enabled 改為其他值即可(默認(rèn)是detect)。
- 文件輸出
默認(rèn),Spring Boot只輸出日志到console。如果還想輸出到文件,需要設(shè)置logging.file或logging.path屬性。
它們的組合如下:
logging.file logging.path Example Description
無 無 只輸出到console
具體文件名 無 my.log console和日志文件。文件名還可以帶路徑
無 具體路徑 /var/log console和路徑下的spring.log。路徑可絕對可相對
- 日志級別
所有支持的日志系統(tǒng)在Spring的Environment(例如在application.properties里)都可以通過’logging.level.*=LEVEL’(’LEVEL’是TRACE, DEBUG, INFO, WARN,ERROR, FATAL, OFF中的一個)來設(shè)置日志級別。root logger可以通過logging.level.root來配置。
示例:application.properties
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
- 自定義日志配置
將相應(yīng)jar包放到依賴中,即可激活對應(yīng)的日志框架。將日志的配置文件放到classpath的根目錄下,或者放到logging.config指定路徑下,就可以自定義日志的輸出。
注意
因?yàn)閘ogging實(shí)在ApplicationContext被創(chuàng)建之前就初始化的,因此無法通過@Configuration注解類的@PropertySources來控制日志。而只能通過系統(tǒng)屬性,環(huán)境變量和Spring Boot的外部配置文件等來配置
與日志系統(tǒng)相對應(yīng)的文件會被自動加載:
日志系統(tǒng) 配置文件
logback logback-spring.xml, logback-spring.groovy, logback.xml,logback.groovy
Log4j log4j-spring.properties, log4j-spring.xml, log4j.properties,log4j.xml
Log4j2 log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging) logging.properties
注意
推薦使用-spring后綴的配置文件,例如logback-spring.xml,而非logback.xml。否則Spring可能無法完全控制log的初始化。
注意
Java Util Logging可能會導(dǎo)致類加載問題,不推薦使用。
- Logback擴(kuò)展
Spring Boot為Logback提供了一些高級配置屬性??梢栽趌ogback-spring.xml中使用。
注意
不能再logback.xml中使用,因?yàn)榇宋募虞d的太早。要么在logback-spring.xml中使用,要么定義logging.confi屬性。
6.1 Profile特定的配置
<springProfile> 標(biāo)簽允許你基于Spring profiles加入或者排除一些配置。
例如:
<springProfile name="staging">
</springProfile>
<springProfile name="dev, staging">
</springProfile>
<springProfile name="!production">
</springProfile>
6.2 Environment屬性
<springProperty> 標(biāo)簽允許你在logback配置文件中使用Spring Environment的屬性。這可以讓你在logback配置中使用application.properties中的值。
例如:
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
<remoteHost>${fluentHost}</remoteHost>
...
</appender>
六、開發(fā)web應(yīng)用
Spring Boot非常適合開發(fā)web應(yīng)用。你可以使用內(nèi)嵌的Tomcat,Jetty或Undertow輕松創(chuàng)建一個HTTP服務(wù)器。大多數(shù)的web應(yīng)用都使用spring-boot-starter-web模塊進(jìn)行快速搭建和運(yùn)行。
- Spring MVC
Spring Web MVC框架是一個富”模型,視圖,控制器”的web框架。 允許你創(chuàng)建特定的@Controller或@RestController beans來處理傳入的HTTP請求。 使用@RequestMapping注解可以將控制器中的方法映射到相應(yīng)的HTTP請求。
Spring Boot為MVC提供了如自動配置,模板引擎等很多特性。
1.1 自動配置
Sprint boot為mvc增加如下自動配置:
引入ContentNegotiatingViewResolver和BeanNameViewResolver beans。
① ContentNegotiatingViewResolver是ViewResolver的一種實(shí)現(xiàn),其根據(jù)請求的media type來為請求選擇一個合適的View。請求的mediatype由ContentNegotiationManager決定。一旦請求的media type被決定,這個resolver查詢所有的view resolver,并返回最匹配的??梢灾付–ontentNegotiatingViewResolver 的defaultViews屬性,在mediatype匹配時將使用此defaultViews指定的viewResolver。
例如,一個/view.html的請求會去尋找content type為text/html的viewresolver;一個路徑為/view,并且header中Accept為text/html的請求也同理。
② BeanNameViewResolver也是一種viewresolver,簡單的將view name解釋成bean
name。如controller中返回”view”,會去找id為view的bean。
對靜態(tài)資源的支持,包括對WebJars的支持。
自動注冊Converter,GenericConverter,F(xiàn)ormatter beans
Converter<S,T>用來將S轉(zhuǎn)換成T
對HttpMessageConverters的支持。
可將對象轉(zhuǎn)換成Http request/response,或者相反。Spring MVC中,object可以自動轉(zhuǎn)換成Json(Jackson庫)或XML(Jacksonxml或者jaxb)。String使用utf-8編碼。
自動注冊MessageCodesResolver。
對靜態(tài)index.html的支持。
對自定義Favicon的支持。
ConfigurableWebBindingInitializer bean的自動使用。
※ 若要完全掌控springmvc,應(yīng)添加自己的@Configuration和@EnableWebMVC注解的類。若想保留Spring boot mvc的特性,同時添加額外的mvc配置(如攔截器,formatters,view controllers等),你可以添加自己的WebMvcConfigurerAdapter類型的@Bean(不使用@EnableWebMVC注解)。
1.2 靜態(tài)內(nèi)容
默認(rèn)情況下,Spring Boot從classpath的/static(/public,/resources或/META-INF/resources)的文件夾或從ServletContext根目錄提供靜態(tài)內(nèi)容。
這使用了Spring MVC的ResourceHttpRequestHandler,所以你可以通過添加自己的WebMvcConfigurerAdapter并覆寫addResourceHandlers方法來改變這個行為(加載靜態(tài)文件)。
如果你的應(yīng)用將被打包成jar,那就不要使用src/main/webapp文件夾。盡管該文件夾是一個共同的標(biāo)準(zhǔn),但它僅在打包成war的情況下起作用,并且如果產(chǎn)生一個jar,多數(shù)構(gòu)建工具都會靜悄悄的忽略它。
1.3 模板引擎
Spring boot支持以下模板引擎的自動配置:freemarker, groovy, thymeleaf, velocity, mustache。
Boot自動從src/main/resources/templates中搜索模板。
使用內(nèi)置servlet容器時要避免使用jsp,原因如下:
內(nèi)置tomcat不支持執(zhí)行jar里的jsp。
Jetty在jsp時不支持內(nèi)置容器個格式。
Undertow不支持jsp。
1.4 Error Handling
Spring Boot默認(rèn)提供一個/error映射用來以合適的方式處理所有的錯誤,并且它在servlet容器中注冊了一個全局的 錯誤頁面。
想要完全替換默認(rèn)行為,可以實(shí)現(xiàn)ErrorController接口,或者實(shí)現(xiàn)BasicErrorController類,由自定義的Controller處理錯誤。
也可以通過@ContorllerAdavice注解+@ExceptionHandler注解定制某個controller或exception類別要返回的JSON文檔。如:
@ControllerAdvice(basePackageClasses = FooController.class)
public class FooControllerAdvice extends ResponseEntityExceptionHandler {
@ExceptionHandler(YourException.class)
@ResponseBody
ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
HttpStatus status = getStatus(request);
return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
}
}
- 嵌入的servlet容器
Spring Boot支持內(nèi)嵌的Tomcat, Jetty和Undertow服務(wù)器。多數(shù)開發(fā)者只需要使用合適的’Starter POM’來獲取一個完全配置好的實(shí)例即可。默認(rèn)情況下,內(nèi)嵌的服務(wù)器會在8080端口監(jiān)聽HTTP請求。
2.1 將Servlets, filters, listeners注冊為bean
所有定義為bean的servlets,filters,listeners都將被嵌入的容器注冊。如果只有一個servlet,它將被map到/,否則bean的名字會作為path前綴。Filters都將map到/*。
也可以使用ServletRegistrationBean,FilterRegistrationBean and ServletListenerRegistrationBean更完整的控制。
2.2 通過注解掃描servlet, filter listener
使用嵌入式容器時,要實(shí)現(xiàn)@WebServlet,@WebFilter, @Weblistener的自動注冊,需要使用@ServletComponentScan。使用獨(dú)立容器時此注解無用。
2.3 Servlet Context 初始化
嵌入的servlet容器不會直接執(zhí)行Servlet3.0+的javax.servlet.ServletContainerInitializer接口,或者Spring的 org.springframework.web.WebApplicationInitializer接口。這是為了避免有些被設(shè)計為運(yùn)行在war內(nèi)的第三方庫會破壞sprint boot應(yīng)用。獨(dú)立httpserver下實(shí)現(xiàn)WebApplicationInitializer即可在代碼中配置ServletContext,代替web.xml。
若需要在spring boot應(yīng)用中進(jìn)行servlet context 初始化,你應(yīng)該注冊一個實(shí)現(xiàn)了org.springframework.boot.context.embedded.ServletContextInitializer接口。
2.4 EmbeddedWebApplicationContext
此類是一種特殊的WebApplicationContext,啟動時會搜索一個EmbeddedServletContainerFactory,例如TomcatEmbeddedServletContainerFactory, JettyEmbeddedServletContainerFactory, or UndertowEmbeddedServletContainerFactory。Spring boot會自動配置這些。
2.5 配置嵌入式servlet容器
2.5.1 可以在如application.properties文件中配置servlet容器所用的屬性
包括:
server.port:http監(jiān)聽端口
server.address: 要綁定的接口地址
server.session.persistence: session持久化
server.session.timeout:session超時時間
server.session.store-dir:session數(shù)據(jù)的location
server.session.cookie.*: session-cookie配置。
server.error.path:error page的地址
server.ssl.key-store, server.ssl.key-store-password, server.ssl.key-password: ssl的配置
server.compression.enabled: http response壓縮
server.compression.min-response-size:壓縮所需的最小size,默認(rèn)時2048字節(jié)
server.compression.mime-types:要壓縮的response content 類型。默認(rèn)時text/html, text/xml, text/plain, text/css
2.5.2 也可通過實(shí)現(xiàn)EmbeddedServletContainerCustomizer接口在代碼中修改屬性
2.5.3 也可直接實(shí)現(xiàn)TomcatEmbeddedServletContainerFactory bean來配置
七、Security
啟用Security
當(dāng)spring security在classpath中(即引入spring-boot-starter-security pom),web應(yīng)用將自動啟用安全限制,并且默認(rèn)啟用basic認(rèn)證。
也可通過@EnableGlobalMethodSecurity注解添加方法級別的安全限制。配置Security
默認(rèn)的AuthenticationManager有一個用戶,名為user, 密碼會打印在log中,也可設(shè)置security.user.password屬性修改密碼。
默認(rèn)的security配置由SecurityAutoConfiguration配置類及其導(dǎo)入的配置類(SpringBootWebSecurityConfiguration配置web security, AuthenticationManagerConfiguration配置認(rèn)證,此類在非web應(yīng)用也適用)實(shí)現(xiàn)。
若要完全關(guān)閉默認(rèn)的web security配置,可以添加一個帶有@EnableWebSecurity的bean,這樣并不會關(guān)閉authentication manager配置。
@EnableWebSecurity注解使用方法
將此注解添加到帶有@Configuration注解,并且實(shí)現(xiàn)了WebSecurityConfigurer接口或繼承WebSecurityConfigurerAdapter類的類上面,即可用此類替代xml設(shè)置web
security。同時還可將配置內(nèi)容放到外部屬性文件中。
若也想關(guān)閉authentication manager配置,你可以增加一個AuthenticationManager的bean,或者通過將AuthenticationManagerBuilder注入到@Configuration類的一個方法中來配置全局的AuthenticationManager。
- Security帶來的特性
Web應(yīng)用中使用Spring Security以后,你可以獲得如下基本特性:
一個帶有in-memory store的AuthenticationManager,和一個user(查看SecurityProperties.User獲取user的屬性)。
通用靜態(tài)資源路徑不會被安全限制:css/, /js/, /images/* and */favicon.ico
其他部分都會應(yīng)用Http Basic安全保護(hù)。
安全事件都會被發(fā)布到spring的ApplicationEventPublisher(包括認(rèn)證成功,認(rèn)證失敗以及拒絕訪問等)
Spring Security提供的常見底層特性(HSTS, XSS, CSRF, 緩存)默認(rèn)都被開啟。
HSTS是什么
HTTP Strict Transport Security,HTTP嚴(yán)格傳輸安全。HSTS的作用是強(qiáng)制客戶端(如瀏覽器)使用HTTPS與服務(wù)器創(chuàng)建連接。服務(wù)器開啟HSTS的方法是,當(dāng)客戶端通過HTTPS發(fā)出請求時,在服務(wù)器返回的超文本傳輸協(xié)議響應(yīng)頭中包含Strict-Transport-Security字段。非加密傳輸時設(shè)置的HSTS字段無效。
參考: http://www.chinaz.com/program/2015/0511/405146.shtml
所有上面的配置都可以通過外部屬性文件修改。想要在不改變?nèi)魏纹渌詣优渲锰匦缘那疤嵯赂采w訪問規(guī)則,可以增加一個WebSecurityConfigurerAdapter類型的bean。
如果開啟了spring-boot-actuator,會有如下特性:
- 即使應(yīng)用路徑不受保護(hù),被管理的路徑也會受到保護(hù)。
- 安全相關(guān)的事件被轉(zhuǎn)換為AuditEvents(審計事件),并發(fā)布給AuditService。
- 默認(rèn)的用戶有ADMIN和USER的角色。
使用外部屬性能夠修改Actuator(執(zhí)行器)的安全特性(management.security.*)。為了覆蓋應(yīng)用程序的訪問規(guī)則,你可以添加一個WebSecurityConfigurerAdapter類型的@Bean。同時,如果不想覆蓋執(zhí)行器的訪問規(guī)則,你可以使用@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)注解該bean,否則使用@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)注解該bean。
八、使用SQL數(shù)據(jù)庫
Spring Boot項目引入spring-boot-starter-data-jpa等即可使用Spring Data與DB交互。除了spring框架提供的JdbcTemplate以及ORM,Spring Data還提供了其他級別的功能,如創(chuàng)建Repository接口的實(shí)現(xiàn),然后基于方法名產(chǎn)生queries。
- 配置數(shù)據(jù)源
Java的javax.sql.DataSource接口提供了一個標(biāo)準(zhǔn)的使用數(shù)據(jù)庫連接的方法。傳統(tǒng)做法是,一個DataSource使用一個URL和用戶名/密碼去初始化一個數(shù)據(jù)庫連接。
1.1 內(nèi)嵌數(shù)據(jù)庫
Spring boot支持自動配置三種in-memory的嵌入式DB:H2, HSQL,Derby。
無需提供URL,引入如下依賴即可使用。例如,典型的pom如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
上文可以使Spring Boot自動為應(yīng)用配置in-memory的hsqldb數(shù)據(jù)庫,并建立連接。
1.2 連接到一個生產(chǎn)環(huán)境數(shù)據(jù)庫
在生產(chǎn)環(huán)境中,數(shù)據(jù)庫連接可以使用DataSource池進(jìn)行自動配置。Spring boot自動配置DataSource池時的選擇順序如下:
由于Tomcat數(shù)據(jù)源連接池的性能和并發(fā),在tomcat可用時,我們總是優(yōu)先使用它。
如果HikariCP可用,我們將使用它。
如果Commons DBCP可用,我們將使用它,但在生產(chǎn)環(huán)境不推薦使用它。
最后,如果Commons DBCP2可用,我們將使用它。
如果使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa ‘starter POMs’,你將會自動獲取對tomcat-jdbc的依賴。
若要修改默認(rèn)的數(shù)據(jù)源類型,或者指定其他的數(shù)據(jù)源類型,可以在application.properties中指定。
例如:
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=xxxxxHikariCP
注:使用MySQL時要增加mysql connector的依賴。
- 使用JdbcTemplate
Spring的JdbcTemplate和NamedParameterJdbcTemplate類將被自動配置,你可以在自己的beans中通過@Autowire直接注入它們。
例如:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final JdbcTemplate jdbcTemplate;
@Autowired
public MyBean(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
- JPA和Spring Data
Spring-boot-starter-data-jpa提供如下依賴:
Hibernate
Spring Data JPA
Spring ORMs
3.1 Entity類
傳統(tǒng)上,JPA實(shí)體需要在persistence.xml中聲明。Spring boot中無需這樣,它可以自動搜索Entity。
默認(rèn)在主配置類(標(biāo)記有@EnableAutoConfiguration 或者 @SpringBootApplication)下的所有包會被搜索,并且會搜索帶有@Entity, @Embeddable 或者 @MappedSuperclass的類。
3.2 Spring Data JPA Repositories
Spring Data JPA倉庫(repositories)是用來定義訪問數(shù)據(jù)的接口。JPA會根據(jù)你的方法名自動創(chuàng)建查詢。比如,一個CityRepository接口可能聲明一個findAllByState(String state)方法,用來查找給定狀態(tài)的所有城市。
繼承Repository 、CrudRepository或者PagingAndSortingRepository接口的接口即為Spring JPA的repositories。Spring Boot會自動搜索這些接口,并通過方法名自動生成JPA queries。更復(fù)雜的查詢可借助Spring Data的Query注解。
3.3 創(chuàng)建和刪除JPA db
默認(rèn)情況下,只有使用嵌入式DB(H2, HSQL或Derby)時,jpa數(shù)據(jù)庫才會被自動創(chuàng)建。
可以通過spring.jpa.*屬性來配置jpa,例如:
spring.jpa.hibernate.ddl-auto=create-drop可開啟自動創(chuàng)建和刪除表,并且默認(rèn)情況下,ApplicationContext啟動之后才會執(zhí)行DDL。
spring.jpa.generate-ddl 也可以用來配置生成表,但是Hibernate自動配置下,該選項不會被激活,因?yàn)镠ibernate的ddl-auto屬性更適用。
九、使用NoSQL
Spring Data支持MongoDB, Neo4J, Elasticsearch, Solr, Redis, Gemfire, Couchbase 和Cassandra等NoSQL技術(shù)。
Spring Boot可以自動配置其中的Redis, MongoDB, Elasticsearch, Solr 和 Cassandra。其他需要手動配置。
- Redis
spring-boot-starter-redis自動導(dǎo)入依賴。Spring boot會自動配置RedisConnectionFactory, StringRedisTemplate 或者RedisTemplate。默認(rèn),這些實(shí)例會連接localhost:6379。
例子:
@Component
public class MyBean {
private StringRedisTemplate template;
@Autowired
public MyBean(StringRedisTemplate template) {
this.template = template;
}
// ...
}
如果你添加一個自己的任何自動配置類型的@Bean,它將替換默認(rèn)的(除了RedisTemplate的情況,它是根據(jù)bean的名稱’redisTemplate’而不是它的類型進(jìn)行排除的)。如果在classpath路徑下存在commons-pool2,默認(rèn)你會獲得一個連接池工廠。
MongoDB
spring-boot-starter-data-mongodb導(dǎo)入依賴。
Spring boot自動配置MongoDbFactory和MongoTemplate。默認(rèn)實(shí)例使用mongodb://localhost/test
可設(shè)置以下屬性:
spring.data.mongodb.uri (mongodb3.0)
spring.data.mongodb.host (mongo 2.x)
spring.data.mongodb.port
Spring Data MongoDB也支持和Spring Data JPA一樣的Repository接口,Spring Data會根據(jù)方法名自動生成queries。Solr
Apache Solr是個搜索引擎。 Sprint Boot利用Spring Data Solr為Solr4客戶端庫提供基本的自動配置。spring-boot-starter-datasolr導(dǎo)入依賴。Solr5暫不支持。
Spring Boot自動配置SolrServer,默認(rèn)連接localhost:8983/solr
Spring Data也為Solr提供與JPA一樣的Repositories,只不過實(shí)體注解為@SolrDocument。Elasticsearch
Elastic Search是一個開源的,分布式,實(shí)時搜索和分析引擎。Spring Boot利用Spring Data Elasticserach為Elasticsearch提供基本的自動配置。spring-boot-starter-data-elasticsearch導(dǎo)入依賴。
Spring boot自動配置ElasticsearchTemplate或Client實(shí)例,并且默認(rèn)連接一個本地的內(nèi)存服務(wù)器(即一個NodeClient),可設(shè)置spring.data.elasticsearch.cluster-nodes連接到remote server(TransportClient)。
Spring Data也為Elasticsearch提供與JPA一樣的Repositories,只不過實(shí)體注解為@Document。
十、緩存
Spring 框架支持透明地為應(yīng)用添加緩存。其核心是抽象層將緩存應(yīng)用到方法,減少執(zhí)行次數(shù)??梢允褂肑SR-107(JCache)注解后者水平自己的緩存注解實(shí)現(xiàn)緩存。
JCache示例:
import javax.cache.annotation.CacheResult;
import org.springframework.stereotype.Component;
@Component
public class MathService {
@CacheResult
public int computePiDecimal(int i) {
// ...
}
}
Cache抽象層并不提供真實(shí)的存儲,它依賴于org.springframework.cache.Cache 和 org.springframework.cache.CacheManager提供的抽象。開啟@EnableCaching之后,SpringBoot會根據(jù)實(shí)現(xiàn)自動配置一個合適的CacheManager。
spring-boot-starter-cache導(dǎo)入依賴。
Spring Boot會依如下順序檢測緩存provider。
Generic
JCache (JSR-107)
EhCache 2.x
Hazelcast
Infinispan
Redis
Guava
Simple
也可使用spring.cache.type指定使用哪一種緩存。
若由Spring Boot自動配置CacheManager, 你可以通過實(shí)現(xiàn)CacheManagerCustomizer接口在cachemanager在完全初始化以前調(diào)整其配置:
@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override
public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setCacheNames(Arrays.asList("one", "two"));
}
};
}
Generic (自定義Cache)
當(dāng)至少自定義了一個org.springframework.cache.Cache bean時,Generic caching會被啟用,并且會配置一個CacheManager來包裝它們。JCache
當(dāng)javax.cache.spi.CachingProvider(這是個JSR107兼容的緩存庫)在classpath中時,JCache會被啟動。當(dāng)有多個provider時,必須通過spring.cache.jcache.provider明確指定一個。還可通過spring.cache.jcache.config來指定配置文件的位置。
有一些方法可以定制化javax.cache.cacheManager:
可以在啟動時指定spring.cache.cache-names創(chuàng)建caches。也可定義javax.cache.configuration.Configuration bean去定制化。
org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer beans會被調(diào)用,并傳入CacheManager來定制。
EhCache2.x
在classpath跟路徑下如果發(fā)現(xiàn)了ehcache.xml,EhCache2.x會被使用。也可使用指定spring.cache.ehcache.config=classpath:config/another-config.xml其他文件。Redis
若配置了Redis,RedisCacheManager會被自動配置。也可以由spring.cache.cache-names指定。
Hazelcast和Infinispan略。Guava
如果Guava可用,GuavaCacheManager會被配置。也可通過spring.cache.cache-names指定。Simple
如果上述選項都沒成功,一個使用ConcurrentHashMap的簡單實(shí)現(xiàn)會被配置為cache store.
十一、消息
Spring Framework框架為集成消息系統(tǒng)提供了擴(kuò)展支持:從使用JmsTemplate簡化JMS API,到實(shí)現(xiàn)一個完整異步消息接收的底層設(shè)施。
Spring AMQP提供一個相似的用于’Advanced Message Queuing Protocol’的特征集,并且Spring Boot也為RabbitTemplate和RabbitMQ提供了自動配置選項。
Spring WebSocket提供原生的STOMP消息支持,并且Spring Boot通過starters和一些自動配置也提供了對它的支持。
- JMS
javax.jms.ConnectionFactory接口提供了一個標(biāo)準(zhǔn)的用于創(chuàng)建一個javax.jms.Connection的方法,javax.jms.Connection用于和JMS代理(broker)交互。Spring Boot為收發(fā)消息提供了自動配置。
1.1 ActiveMQ 支持
SpringBoot檢測到ActiveMQ在classpath中可用時,會配置一個ConnectionFactory??膳渲萌缦聦傩裕?br>
spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret
1.2 HornetQ支持
支持的屬性有embedded,native。spring-boot-starter-hornetq導(dǎo)入依賴。
1.3 Artemis 支持
Apache Artemis是在2015年HornetQ被捐給Apache基金會以后建立的,所有特性和HornetQ一樣。spring-boot-starter-artemis導(dǎo)入依賴
- AMQP
AMQP是一個面向消息的,平臺中立、wire-level(指的是并非定義api和庫,而是定義會話字節(jié)流,類似http)的中間件協(xié)議。
2.1 RabbitMQ支持
RabbitMQ是輕量級,可靠的,可擴(kuò)展的,輕便的基于AMQP協(xié)議的消息代理。Spring利用RabbitMQ實(shí)現(xiàn)AMQP協(xié)議。可通過spring.rabbitmq.*屬性組來配置,如:
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret
Spring boot會自動配置AmqpTemplate,AmqpAdmin,RabbitMessagingTemplate。
十二、發(fā)送郵件
Spring Boot自動配置JavaMailSender來發(fā)送郵件。spring-boot-starter-mail導(dǎo)入依賴。
可通過spring.mail.*屬性組來配置。
十三、JTA處理分布式事務(wù)
Spring Boot使用一個Atomkos或Bitronix的內(nèi)嵌事務(wù)管理器來支持跨多個XA資源的分布式JTA事務(wù)。當(dāng)部署到一個恰當(dāng)?shù)腏2EE應(yīng)用服務(wù)器時也會支持JTA事務(wù)。
當(dāng)發(fā)現(xiàn)一個JTA環(huán)境時,Spring Boot將使用Spring的JtaTransactionManager來管理事務(wù)。自動配置的JMS,DataSource和JPA beans將被升級以支持XA事務(wù)。
你可以使用標(biāo)準(zhǔn)的@ransactional來參與到一個分布式事務(wù)中。可設(shè)置ring.jta.enabled=alse來禁用JTA自動配置功能。
spring-boot-starter-jta-atomikos和spring-boot-starter-jta-bitronix導(dǎo)入依賴。
十四、Spring Session
Spring Session為管理用戶的session信息提供支持。若web應(yīng)用的classpath中有spring session 和spring data redis,spring boot會通過@EnableRedisHttpSession自動配置Spring session。Session數(shù)據(jù)被存儲在redis中,超時期限可通過server.session.timeout設(shè)置。
十五、測試
spring-boot-starter-test提供以下庫:
? spring-test提供集成測試支持
? JUnit
? Hamcrest—為JUnit提供assertThat支持
? Mockito
- 測試Spring Boot應(yīng)用
Spring Boot提供@SpringApplicationConfiguration替代spring-test標(biāo)準(zhǔn)的@ContextConfiguration注解。測試中使用@SpringApplicationConfiguration配置ApplicationContext,ApplicationContext會被SpringApplication創(chuàng)建,并且?guī)в蓄~外的Spring boot的特性。實(shí)例:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(SampleDataJpaApplication.class)
public class CityRepositoryIntegrationTests {
@Autowired
CityRepository repository;
// ...
}
另外加上@WebIntegrationTest 或 @WebAppConfiguration注解,會使得context loader認(rèn)為你在測試web應(yīng)用。例如,為測試類加上@WebIntegrationTest會以web應(yīng)用方式啟動測試:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(SampleDataJpaApplication.class)
@WebIntegrationTest
public class CityRepositoryIntegrationTests {
@Autowired
CityRepository repository;
RestTemplate restTemplate = new TestRestTemplate();
// ... interact with the running server
}
可以使用@WebIntegrationTest注解的server.port等屬性修改端口。例如:@WebIntegrationTest(“server.port:9000”)。如果將server.port和management.port置為0,應(yīng)用的集成測試將使用任意端口,例如:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(MyApplication.class)
@WebIntegrationTest({"server.port=0", "management.port=0"})
public class SomeIntegrationTests {
// ...
}
十六、Actuator(促動器):: Production-ready features
Springboot提供一些特性幫你在應(yīng)用部署到生產(chǎn)環(huán)境后監(jiān)視和管理應(yīng)用。可通過HTTP,JMX甚至remote shell(SSH,Telnet)來管理和監(jiān)視。審計,健康和數(shù)據(jù)采集會自動應(yīng)用到你的應(yīng)用。
HTTP只有在基于Spring MVC的應(yīng)用中才可用。
開啟production-ready 特性
spring-boot-actuator提供Spring boot的production ready特性。
Actuator是機(jī)器術(shù)語,指移動或控制其他東西的機(jī)械設(shè)備。Actuator通過微小的改變產(chǎn)生很大的移動。
spring-boot-starter-actuator導(dǎo)入依賴。endpoints 端點(diǎn)
Actuator端點(diǎn)使你可以監(jiān)視應(yīng)用并與之交互。Spring boot包含一些內(nèi)置的端點(diǎn)(例如health端點(diǎn)),你也可以自己增加。
端點(diǎn)被暴露的方式取決于選擇的技術(shù)類型。大多應(yīng)用選擇HTTP監(jiān)視,這樣端點(diǎn)的ID被map到URL。如health端點(diǎn)被map到/health.
2.1 常用端點(diǎn)
ID 描述 是否敏感
actuator 為其他端點(diǎn)提供一個基于超媒體(hypermedia-based)的發(fā)現(xiàn)頁面。需要Spring HATEOAS支持 true
autoconfig 顯示一個auto-configuration的報告,該報告展示所有auto-configuration候選者及它們被應(yīng)用或未被應(yīng)用的原因 true
beans 顯示一個應(yīng)用中所有Spring Beans的完整列表 true
health 展示應(yīng)用的健康信息(當(dāng)使用一個未認(rèn)證連接訪問時顯示一個簡單的’status’,使用認(rèn)證連接訪問則顯示全部信息詳情) false
info 顯示任意的應(yīng)用信息 false
dump 執(zhí)行一個線程轉(zhuǎn)儲 true
mappings 顯示一個所有@RequestMapping路徑的整理列表 true
trace 顯示trace信息(默認(rèn)為最新的一些HTTP請求) true
什么是”是否敏感”?
取決于你如何暴露端點(diǎn),敏感性可以用作安全指示。例如,如果使用HTTP并且打開了Spring Security,那么訪問敏感端點(diǎn)要求用戶名和密碼。
2.2 CORS跨域資源共享支持
Cross-origin resource sharing,是個W3C規(guī)格,它為Web服務(wù)器定義了一種方式,允許網(wǎng)頁從不同的域訪問其資源(如字體),簡言之,CORS就是為了讓AJAX可以實(shí)現(xiàn)可控的跨域訪問而生的。Actuator的MVC端點(diǎn)可以配置支持該場景:
endpoints.cors.allowed-origins=http://example.com
endpoints.cors.allowed-methods=GET,POST
- 通過HTTP監(jiān)控和管理
開發(fā)Spring MVC應(yīng)用時,Spring Boot Actuator會自動配置所有打開的端點(diǎn),并通過HTTP暴露。默認(rèn)的約定是端點(diǎn)id被map到url,如health到/health。
3.1 保護(hù)敏感端點(diǎn)
如果應(yīng)用了Spring security,所有通過HTTP暴露的敏感的端點(diǎn)都會被保護(hù)。默認(rèn)會使用基本認(rèn)證(basic authentication,用戶名為user,密碼為應(yīng)用啟動時在控制臺打印的密碼)。
你可以使用Spring屬性改變用戶名,密碼和訪問端點(diǎn)需要的安全角色。例如,在application.properties中添加下列配置:
security.user.name=admin
security.user.password=secret
management.security.role=SUPERUSER
3.2 定制管理端點(diǎn)的路徑
可通過如下設(shè)置為端點(diǎn)的url設(shè)置前綴:
management.context-path=/manage
1
1
也可修改端點(diǎn)的id或者path來達(dá)到修改path的目的:
endpoints.health.id = fuck
endpoints.health.path = /fuck/damn
3.3 定制管理服務(wù)器的端口
針對基于云的部署,使用默認(rèn)HTTP端口暴露管理端點(diǎn)比較明智。如果應(yīng)用運(yùn)行在自己的數(shù)據(jù)中心,可以如下修改端口:
management.port=8081
一般情況下內(nèi)部應(yīng)用的管理端口都被防火墻保護(hù),不對外開放,因此可以如下關(guān)掉保護(hù):
management.security.enabled=false
※ 只有在啟用Spring security才有必要明顯的關(guān)閉,否則反而可能破壞應(yīng)用。
3.4 定制管理服務(wù)器地址:
management.port=8081
management.address=127.0.0.1
3.5 關(guān)掉http端點(diǎn)
management.port=-1
- 度量指標(biāo)Metrics
Spring Boot Actuator包括一個支持’gauge’和’counter’級別的度量指標(biāo)服務(wù)?!痝auge’記錄一個單一值;’counter’記錄一個增量(增加或減少)。
所有HTTP請求的度量指標(biāo)都會被自動記錄,通過metrics端點(diǎn)(/metrics)即可訪問。
4.1 系統(tǒng)度量指標(biāo)
Spring Boot暴露以下系統(tǒng)指標(biāo):
系統(tǒng)內(nèi)存總量(mem),單位:Kb
空閑內(nèi)存數(shù)量(mem.free),單位:Kb
處理器數(shù)量(processors)
系統(tǒng)正常運(yùn)行時間(uptime),單位:毫秒
應(yīng)用上下文(就是一個應(yīng)用實(shí)例)正常運(yùn)行時間(instance.uptime),單位:毫秒
系統(tǒng)平均負(fù)載(systemload.average)
堆信息(heap,heap.committed,heap.init,heap.used),單位:Kb
線程信息(threads,thread.peak,thead.daemon)
類加載信息(classes,classes.loaded,classes.unloaded)
垃圾收集信息(gc.xxx.count, gc.xxx.time)
4.2 數(shù)據(jù)源指標(biāo)
以下指標(biāo)會被暴露(前綴都是datasource.):
活躍連接數(shù)(datasource.xxx.active)
當(dāng)前連接池使用率(datasource.xxx.usage)
4.3 緩存指標(biāo)
以下指標(biāo)會被暴露:
當(dāng)前cache大小(cache.xxx.size)
命中率(cache.xxx.hit.ratio)
未命中率(cache.xxx.miss.ratio)
4.4 tomcat session指標(biāo)
若使用tomcat做嵌入的servlet容器,session指標(biāo)會被暴露:
活躍session數(shù):httpsessions.active
最大session數(shù):httpsessions.max
十七、部署SpringBoot應(yīng)用
Spring Boot靈活的打包選項幫你更容易的將Spring Boot 應(yīng)用部署到云平臺,容器鏡像,虛擬機(jī)或者實(shí)體機(jī)。
部署到云
Spring Boot的可執(zhí)行jar包可以部署到大多數(shù)流行的PaaS(Platform as a service)云提供者。這些云提供者要求使用者“帶好自己的容器”;而它們管理應(yīng)用進(jìn)程。所以它們需要一些中間層來將你的應(yīng)用適配到云概念中的一個運(yùn)行進(jìn)程。
兩個流行的云提供者,Heroku和Cloud Foundry,采取一種“buildpack”方式。Buildpack將你部署的代碼打包進(jìn)任何啟動應(yīng)用所需的包里:可能是個JDK和一個java調(diào)用,可能是一個嵌入式web服務(wù)器,也可能是一個完整的應(yīng)用服務(wù)器。一個buildpack是可插拔的,但你最好盡可能少的對它進(jìn)行自定義設(shè)置。這可以減少不受你控制的功能范圍,并最小化開發(fā)和生產(chǎn)環(huán)境的差別。
理想情況下,你的應(yīng)用比如一個Spring boot可執(zhí)行jar包,應(yīng)含有它運(yùn)行所需的一切。
還有OpenShift, Boxfuse和Amazon Web Service也支持Spring boot jar的部署
Goole App Engine只支持Servlet 2.5,要部署Springboot應(yīng)用需要做修改。安裝Spring Boot 應(yīng)用。
除了使用jar –jar運(yùn)行可執(zhí)行jar包,還可以編譯成Unix上的完全可執(zhí)行應(yīng)用:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
CentOS和Ubuntu上都已支持此功能。這樣就可將應(yīng)用以unix/Linux service的方式啟動。
參考鏈接
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/
歡迎關(guān)注 [Java架構(gòu)師社區(qū)][1]公眾號
本文轉(zhuǎn)載自Java架構(gòu)師必看 ,更多內(nèi)容點(diǎn)擊查看!