Part IV. Spring Boot Features(Spring Boot 的特性)SpringApplication
通常放在了main函數(shù)中加缘,作為spring-boot的啟動(dòng)類
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
}
1. Customizing the Banner(自定義Banner)
Banner將會在系統(tǒng)啟動(dòng)的時(shí)候打印出來,4中方式設(shè)置
在classpath中添加一個(gè)文件banner.txt
通過參數(shù)banner.location來設(shè)置文件的位置诗越,設(shè)置文件的編碼banner.charset(默認(rèn)使用UTF-8)
在classpath中添加一個(gè)文件banner.gif, banner.jpg or banner.png
通過參數(shù)banner.image.location來設(shè)置圖片文件的位置
在banner.txt文件中可以設(shè)置下面的參數(shù):
${application.version}
${application.formatted-version}
${spring-boot.version}
${spring-boot.formatted-version}
${application.title}
通過程序來設(shè)置banner
實(shí)現(xiàn)這個(gè)接口中org.springframework.boot.Banner 的printBanner()方法散罕,在通過SpringApplication.setBanner(…)
來設(shè)置自己實(shí)現(xiàn)的Banner
也可以使用spring.main.banner-mode來設(shè)置是否啟用或者關(guān)閉打印banner功能蹭睡,可選參數(shù)log,off
2. Customizing SpringApplication
通常使用SpringApplication的靜態(tài)方法運(yùn)行车海,為了設(shè)置更多的參數(shù),可以直接new一個(gè)SpringApplication
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
雖然可以通過編程的方式來實(shí)現(xiàn)配置參數(shù)涂邀,但是官方建議使用application.properites來配置瘟仿。更多配置參數(shù)參考SpringApplication Javadoc
3. Application events and listeners
順序如下: ApplicationStartedEvent,ApplicationEnvironmentPreparedEvent比勉,ApplicationPreparedEvent劳较,ApplicationReadyEvent驹止,ApplicationFailedEvent
使用SpringApplication.addListeners(…)添加事件監(jiān)聽器
4. Accessing application arguments(訪問application的參數(shù))
可以依賴注入org.springframework.boot.ApplicationArguments,ApplicationArguments提供了訪問application參數(shù)的方法;
也可以直接把需要的參數(shù)作為屬性观蜗,使用@Value來訪問
5. Using the ApplicationRunner or CommandLineRunner
如果想要在SpringApplication.run(...)執(zhí)行完成前對參數(shù)做一些特殊處理臊恋,可以使用ApplicationRunner,CommandLineRunner這兩個(gè)接口
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
6. Application exit
所有Spring管理的類在結(jié)束之前需要做一些事墓捻,可以使用DisposableBean接口或者@PreDestroy注解抖仅,
如果需要在Application容器結(jié)束后返回一些特殊的Code,可以實(shí)現(xiàn)org.springframework.boot.ExitCodeGenerator 接口
Externalized Configuration
1. Application property files
Spring-boot會從application.properties中尋找配置屬性,application.properties可以放在如下位置:
放在當(dāng)前項(xiàng)目根目錄下
放在當(dāng)前項(xiàng)目根目錄下的/config中
放在classpath根目錄下(推薦)
放在claasspath根目錄下/config中
注意:目錄最深的覆蓋上層的熟悉
也可以通過spring.config.name,spring.config.location在命令行參數(shù)中指定參數(shù)文件的名字和加載位置
2. Profile-specific properties
通常我們需要對測試環(huán)境砖第,開發(fā)環(huán)境撤卢,正式環(huán)境配置不同的參數(shù),我們可以寫多個(gè)配置文件梧兼,
格式 application-{profile}.properties,然后再applicatioin.properties中使用spring.profiles.active來指定使用哪一個(gè)或多個(gè)配置文件(多個(gè)文件使用逗號分隔)放吩,特定的配置文件中的屬性將會覆蓋application.propreties中的屬性
也可以使用 @Profile("...") 來指定使用哪個(gè)文件
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
在application.properties中的參數(shù)可以項(xiàng)目使用,比如:
app.name=MyApp app.description=${app.name} is a Spring Boot application 3. Type-safe Configuration Properties
使用@Value("${property}")來依賴注入屬性有時(shí)候會很麻煩羽杰,尤其是多個(gè)屬性需要注入渡紫。Spring-boot提供一種更加方便的方式@ConfigurationProperties。
首先建立一個(gè)類
@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {
private String username;
private InetAddress remoteAddress;
// ... getters and setters
}
在@EnableConfigurationProperties中指定建立的配置類
@Configuration
@EnableConfigurationProperties(ConnectionProperties.class)
public class MyConfiguration {
}
在需要使用的類中使用@Autowired注入ConnectionProperties
另一種方式考赛,可以不用使用EnableConfigurationProperties(ConnectionProperties.class), 直接在ConnectionProperties上添加@Component
4. Relaxed binding(簡便的綁定方式)
@ConfigurationProperties(prefix="person")
public class OwnerProperties {
private String firstName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
5. @ConfigurationProperties Validation
Spring-boot 支持使用JSR-303的方式對@ConfigurationProperties的注解類的屬性進(jìn)行校驗(yàn)惕澎,并且使用@Valid 來觸發(fā)校驗(yàn)
@Component
@ConfigurationProperties(prefix = "connection")
public class ConnectionProperties {
@NotEmpty
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
@Valid
private ConnectionProperties connectionProperties;
@RequestMapping("/login")
String login() {
return "Login Successful!=" + connectionProperties.getUserName();
}
}
6. @ConfigurationProperties vs. @Value
Feature | @ConfigurationProperties | @Value |
---|---|---|
Relaxed binding | Yes | No |
Meta-data support | Yes | No |
evaluation | No | Yes |
7. Programmatically setting profiles(編程的方式來設(shè)置profiles)
你可以在application啟動(dòng)之前調(diào)用方法 SpringApplication.setAdditionalProfiles(…);你也可以通過使用ConfigurableEnvironment接口來實(shí)現(xiàn)
Logging(系統(tǒng)日志配置)
1. 使用不同顏色輸出日志
spring.output.ansi.enabled 可選的參數(shù) :
ALWAYS ,DETECT , NEVER 參考api supported value
2. 配置日志文件
logging.file 配置日志文件名稱
logging.path 配置日志文件的路徑
logging.file | logging.path | Example Description |
---|---|---|
(none) | (none) | 控制臺輸出 |
指定日志文件名 | (none) | my.log項(xiàng)目根目錄下輸出日志文件 |
(none) | 指定目錄 | /var/log在指定目錄下生成日志文件 |
當(dāng)日志文件達(dá)到10m將會重新在新的文件中輸出
3. 配置日志輸出級別
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
4. 配置日志輸出的格式
logging.pattern.console : 配置控制臺輸出格式
logging.pattern.file : 配置日志文件輸出格式
Developing web applications(開發(fā)web應(yīng)用)
Spring-boot對大部分應(yīng)用提供了spring mvc 自動(dòng)配置。自動(dòng)配置了下面一些特性:
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
Support for serving static resources, including support for WebJars (see below).
Automatic registration of Converter, GenericConverter, Formatter beans.
Support for HttpMessageConverters (see below).
Automatic registration of MessageCodesResolver (see below).
Static index.html support.
Custom Favicon support.
-
Automatic use of a ConfigurableWebBindingInitializer bean (see below).
如果你想要配置spring mvc 的一些攔截器颜骤, formatters, view controllers等等集灌,你可以創(chuàng)建一個(gè)類繼承于WebMvcConfigurerAdapter;例如:自己配置一個(gè)攔截器@Configuration
@ComponentScan(basePackages = "com.spring.boot.controller3")
public class WebConfigure extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/user/**");
}
}
如果你想要自己實(shí)現(xiàn)RequestMappingHandlerMapping, RequestMappingHandlerAdapter,ExceptionHandlerExceptionResolver, 你可以自己實(shí)現(xiàn)WebMvcRegistrationsAdapter
1. HttpMessageConverters
Spring-boot已經(jīng)包含了常用的HttpMessageConverter复哆,比如自動(dòng)轉(zhuǎn)換對象為JSON或者XML;如果需要自己定義一些HttpMessageConverter,可以使用Spring-boot的HttpMessageConverters類:
@Configuration
public class MyConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = ...
HttpMessageConverter<?> another = ...
return new HttpMessageConverters(additional, another);
}
}
2. Static Content(靜態(tài)資源)
默認(rèn)情況下Spring-boot使用的是Spring-mvc中的ResourceHttpRequestHandler來處理靜態(tài)資源腌零,默認(rèn)靜態(tài)資源的位置是在classpath目錄下或者ServletContext根目錄下的/static (or /public or /resources or/META-INF/resources)梯找;你也可以添加自己的處理方式,通過使用WebMvcConfigurerAdapter中的addResourceHandlers方法益涧。
你也可以自己定義靜態(tài)資源的位置锈锤,使用配置參數(shù)spring.resources.staticLocations
Spring-boot也支持靜態(tài)資源緩存,使用版本號闲询,參考spring-boot文檔靜態(tài)資源處理
3. ConfigurableWebBindingInitializer
默認(rèn)Spring-boot使用的是WebBindingInitializer來初始化WebDataBinder久免,你可以創(chuàng)建自己的一個(gè)WebBindingInitializer,然后使用@Bean扭弧,那么Spring-boot將會使用自己定義的來配置Spring-mvc.參考ConfigurableWebBindingInitializer的實(shí)現(xiàn)阎姥。
5. Template engines
Spring-boot自動(dòng)配置支持以下模板引擎:
FreeMarker
Groovy
Thymeleaf
Velocity (deprecated in 1.4)
Mustache
注意:JSP在Spring-boot中盡量避免使用,當(dāng)使用內(nèi)嵌的Servlet服務(wù)器的時(shí)候會有一些限制鸽捻。參考文檔
使用這些模板引擎呼巴,它們默認(rèn)情況下都會在src/main/resources/templates目錄下尋找模板泽腮。
6. Error Handling
我們可以通過使用@ControllerAdvice為一些特殊的Controller處理一些特殊的Exception
@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);
}
}
7. Custom error pages
為了對不同的錯(cuò)誤狀態(tài)碼顯示不同不錯(cuò)誤頁面,我們可以在/error目錄下面添加一個(gè)文件衣赶;這個(gè)文件可以是html,也可以是模板诊赊;文件的名稱可以狀態(tài)碼,也可以是模板府瞄,比如:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftl
+- <other templates>
更多復(fù)雜的映射碧磅,還可以使用ErrorViewResolver來實(shí)現(xiàn):
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map<String, Object> model) {
// Use the request or status to optionally return a ModelAndView
return ...
}
}
我們也可以通過使用springmvc的特性來處理不同的異常,比如:@ExceptionHandler,@ControllerAdvice遵馆。其他沒有被處理的異常都會被ErrorController攔截處理
8. CORS support(跨站點(diǎn)資源訪問)
在Spring-mvc中已經(jīng)支持跨站點(diǎn)資源訪問鲸郊,只需要在需要訪問的類或方法上面添加注解@CrossOrigin,也可以配置全局的跨站點(diǎn)訪問 參考文檔团搞。
Spring-boot配置全局的跨站點(diǎn)訪問:
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}
l9. Embedded servlet container support(內(nèi)嵌的servlet容器)
Spring-boot 已經(jīng)內(nèi)嵌了Tomcat,Jetty服務(wù)器严望,默認(rèn)監(jiān)聽的端口是8080
9.1 Registering Servlets, Filters, and listeners
當(dāng)使用Spring boot的嵌入式servlet容器時(shí),可以通過Spring bean或掃描Servlet組件的方式注冊Servlet逻恐、Filter和Servlet規(guī)范的所有監(jiān)聽器(例如HttpSessionListener)像吻。
當(dāng)urlMapping不是很復(fù)雜時(shí),可以通過ServletRegistrationBean复隆、FilterRegistrationBean 和ServletListenerRegistrat<wbr>ionBean獲得完整控制拨匆。如果bean實(shí)現(xiàn)了ServletContextInitialize<wbr>r接口的話則可以直接注冊。
@Configuration
@ComponentScan(basePackages = "com.spring.boot.controller3")
public class WebConfigure extends WebMvcConfigurerAdapter {
@Bean
public ServletRegistrationBean getLogServlet(LogServlet logServlet) {
return new ServletRegistrationBean(logServlet, "/logServlet");
}
}
@Component
public class LogServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("Log Servlet welcome!");
writer.close();
}
}
當(dāng)使用@ServletComponentScan掃描Servlet組件時(shí)挽拂,Servlet惭每、過濾器和監(jiān)聽器可以是通過@WebServlet、@WebFilter和@WebListener自動(dòng)注冊
@Configuration
@ServletComponentScan(basePackages = "com.spring.boot.component")
public class WebConfigure extends WebMvcConfigurerAdapter {
}
@WebServlet(urlPatterns = {"/logServlet2"})
public class LogServlet2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("Log Servlet2 welcome!");
writer.close();
}
}
9.2 Servlet Context Initialization
對于這種內(nèi)嵌的Servlet容器亏栈,在初始化的時(shí)候不會去執(zhí)行javax.servlet.ServletContainerInitializer這個(gè)接口台腥,而是執(zhí)行spring的接口org.springframework.web.WebApplicationInitializer。如果你需要在spring-boot的應(yīng)用中去處理初始化的工作绒北,可以注冊一個(gè)Spring Bean實(shí)現(xiàn)接口org.springframework.boot.context.embedded.ServletContextInitializer
@Component
public class AppServletContextInitializer implements ServletContextInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("============ AppServletContextInitializer ===============");
}
}
9.3 Customizing embedded servlet containers(配置嵌入的Servlet容器)
-
在applicat-ion.properties中配置參數(shù)
server.port : 配置監(jiān)聽的端口
server.address : 監(jiān)聽地址
server.session.timeout : session過期時(shí)間
server.session.persistence : 是否需要持久化session
server.session.store-dir : session存儲位置
更多其他配置參考類 ServerProperties
-
通過編程的方式實(shí)現(xiàn)
import org.springframework.boot.context.embedded.*;
import org.springframework.stereotype.Component;
@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setPort(9000);
}
}
實(shí)現(xiàn)EmbeddedServletContainerCustomizer接口黎侈,編程配置參數(shù)
-
如果以上兩種方式你覺得不靈活,你可以使用 TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactoryor UndertowEmbeddedServletContainerFactory
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
return factory;
}
Working with SQL databases(使用SQL數(shù)據(jù)庫)
1. 配置數(shù)據(jù)庫連接池
1. Spring-boot能夠自動(dòng)配置數(shù)據(jù)庫連接池DataSource,自動(dòng)選擇的規(guī)則:
2. 因?yàn)門omcat的連接池效率和并發(fā)性都比較高闷游,所以如果允許峻汉,都會選擇使用
3. 否則,如果HikariCP允許脐往,就會選擇HikariCP
4. 如果Tomcat pooling datasource和HikariCP都不能使用休吠,那么將會選擇使用 DBCP
5. 最后,以上3中都不能使用业簿,就會選擇使用DBCP2
如果你使用了spring-boot-starter-jdbc, spring-boot-starter-data-jpa ,那么Spring-boot將會自動(dòng)配置tomcat-jdbc
也可以通過使用spring.datasource.type來手動(dòng)配置使用哪種瘤礁,比如:配置阿里巴巴開源項(xiàng)目druid
更多的數(shù)據(jù)庫參數(shù)配置,參考類DataSourceProperties
2. Using JdbcTemplate
Spring-boot會自動(dòng)配置JdbcTemplate,可以直接使用@Autowire來注入使用
@Component
public class MyBean {
private final JdbcTemplate jdbcTemplate;
@Autowired
public MyBean(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// ...
}
3. JPA and ‘Spring Data’
在Spring-boot應(yīng)用中辖源,可以使用spring-boot-starter-data-jpa作為一個(gè)開始蔚携,會包含一下依賴:
Hibernate?—?One of the most popular JPA implementations.
Spring Data JPA?—?Makes it easy to implement JPA-based repositories.
Spring ORMs?—?Core ORM support from the Spring Framework.
3.1 Entity Classes And Spring Data JPA Repositories
默認(rèn)情況下希太,Spring-boot會掃描主要配置類(有注解@EnableAutoConfiguration or@SpringBootApplication)下面的所有包,任何被@Entity, @Embeddable or @MappedSuperclass注解的類都會作為實(shí)體;任何繼承了Repository or CrudRepository的接口都會被作為 Repository,不需要任何@Component or Repository
如果你想要自定義尋找的Entity的存放位置酝蜒,可以使用注解@EntityScan誊辉。
Caching 參考文檔
Sending email
Spring框架提供了一個(gè)發(fā)送郵件的類JavaMailSender。
如果在容器中找不到一個(gè)存在的JavaMailSender亡脑,配置了參數(shù)spring.mail.host并且相關(guān)包存在(spring-boot-starter-mail導(dǎo)入相關(guān)包)堕澄,那么就會自動(dòng)創(chuàng)建一個(gè)JavaMailSender。
郵件配置參數(shù)都是以spring.mail開頭霉咨,更多參數(shù)配置參考類: MailProperties
#發(fā)送郵件配置
spring.mail.host=smtp.sina.cn
spring.mail.username=silentwu@sina.cn
spring.mail.password=asdewq
@RestController
@RequestMapping("/mail")
public class MailController {
@Autowired
private JavaMailSender mailSender;
@RequestMapping("/send")
public String sendMail() {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo("380303318@qq.com");
mailMessage.setFrom("silentwu@sina.cn");
mailMessage.setSubject(" 測試簡單文本郵件發(fā)送蛙紫! ");
mailMessage.setText(" 測試我的簡單郵件發(fā)送機(jī)制!途戒! ");
mailSender.send(mailMessage);
return "send mail success...";
}
}
Spring Session 參考文檔
Monitoring and management over JMX 參考文檔