spring-boot-features-custom-failure-analyzer

自定义FailureAnalyzer

Step1:自定义异常

1
2
3
4
5
6
public class BusinessException extends RuntimeException {
public BusinessException(String msg){
super(msg);
}
}

Step2:自定义FailureAnalyzer

1
2
3
4
5
6
7
8
9
10
public class BusinessFailureAnalyzer extends AbstractFailureAnalyzer<BusinessException> {
BusinessFailureAnalyzer(){
}
@Override
protected FailureAnalysis analyze(Throwable throwable, BusinessException e) {
return new FailureAnalysis("business description","business action",e);
}
}

Step3:配置FailureAnalyzer

1
2
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.felix.spring.boot.analyzer.BusinessFailureAnalyzer

Step4:定义一个Service被Spring初始化抛出该异常

1
2
3
4
5
6
7
@Component
public class EchoService implements InitializingBean{
@Override
public void afterPropertiesSet() throws Exception {
throw new BusinessException("business exception");
}
}

Step5:构建一个Spring Application

1
2
3
4
5
6
7
8
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class ApplicationWithBusinessException {
public static void main(String[] args) {
SpringApplication.run(ApplicationWithBusinessException.class,args);
}
}

Step6:运行Spring Application

1
2
3
4
5
6
7
8
9
10
11
***************************
APPLICATION FAILED TO START
***************************
Description:
business description
Action:
business action

spring-boot-application-starters

引言

本文主要介绍spring-boot官方提供的常用的starters,对应的spring-boot版本均为1.4.2.RELEASE,官方文档地址为http://docs.spring.io//spring-boot/docs/1.4.2.RELEASE/reference/html/using-boot-build-systems.html#using-boot-starter,官方提供的starters均以spring-boot-starter-开头,第三方提供的starters均以acme-spring-boot-starter开头,当然你也可以自己定义starters

Database

Name Description Pom
spring-boot-starter-data-redis 集成了Spring Data Redisredis,redis是一种NoSQL数据库 Pom
spring-boot-starter-data-mongodb 集成了Spring Data MongoDBmongodb,mongodb是一种NoSQL数据库 Pom
spring-boot-starter-data-neo4j 集成了Spring Data Neo4jNeo4j,Neo4j是一种图数据库 Pom
spring-boot-starter-data-couchbase 集成了Spring Data CouchbaseCouchbase,couchbase是一种NoSQL数据库 Pom
spring-boot-starter-data-cassandra 集成了Spring Data Cassandracassandra,cassandra是一种开源的分布式NOSQL数据库,最早由facebook开发,后捐赠给Apache Pom
spring-boot-starter-data-gemfire 集成了Spring Data GemFireGemFire,GemFire是一种NoSQL数据库 Pom

Servlet Container

这篇文章解释了什么是一个Servlet Container。目前Servlet Container有很多,详细可以参考维基百科spring-boot集成了以下几款开源的Servlet Container

  • tomcattomcatspring-boot默认集成的Servlet Container
  • undertowundertow是一款轻量级、灵活的、可嵌入的、并支持Web Socket协议的开源容器。
  • jettyjetty是一款由eclipse维护的开源容器,目前使用也很广泛。
Name Description Pom
spring-boot-starter-tomcat spring-boot-starter-web默认集成的容器 Pom
spring-boot-starter-undertow 集成了undertow Pom
spring-boot-starter-jetty 集成了jetty Pom

Rest

Restrepresentational state transfer的缩写,意思是表达性状态转换。Rest是一种架构风格,它包含了一个分布式超文本系统中对于组件、连接器和数据的约束。想了解更多关于Rest点击此处
HATEOASHypermedia as the engine of application state的缩写,意思是超媒体即应用状态引擎。HATEOASRest架构风格中最复杂的约束,也是构建成熟Rest服务的核心。

JAX-RSJava API for RESTful Web Services的缩写,是一个Java编程语言的应用程序接口,支持按照Rest架构风格创建Web服务。目前已知的JAX-RS有4种,Jersey是其中的一种实现,由Sun开发的产品级质量的JAX-RS的参考实现。当然,Jersey也支持HATEOAS约束。

spring-hateoasspring-data-restspring旗下的两个子项目,spring-data-rest包含了spring-hateoas,虽然spring-hateoas实现了HATEOAS,但是spring-data-rest并没有真正的实现JAX-RS规范。

spring-boot提供了以下几种来快速构建Rest服务:

Name Description Pom
spring-boot-starter-web 默认是支持RESTful Pom
spring-boot-starter-hateoas 集成了spring-mvcspring-hateoas Pom
spring-boot-starter-jersey 集成了spring-mvcJersey Pom
spring-boot-starter-data-rest 集成了spring-data-restspring-mvc Pom

Socia API

spring-socialspring旗下的一个扩展子项目,
它主要方便你对FacebookTwitterLinkedIn等SAAS服务提供的API的一个使用。目前spring-social的最新版本是1.1.4.RELEASE。它有以下几个模块组成:

  • spring-social-web
  • spring-social-config
  • spring-social-core
  • spring-social-security

目前已正式发布支持的有FacebookTwitterLinkedIn

  • spring-social-linkedin
  • spring-social-facebook
  • spring-social-twitter

正在孵化的有GithubTripit

  • spring-social-github
  • spring-social-tripit

spring-boot集成了FacebookTwitterLinkedIn

Name Description Pom
spring-boot-starter-social-linkedin 集成了spring-boot-starter-webspring-social-linkedin Pom
spring-boot-starter-social-facebook 集成了spring-boot-starter-webspring-social-facebook Pom
spring-boot-starter-social-twitter 集成了spring-boot-starter-webspring-social-twitter Pom

JTA

JTAJava Transaction API的缩写,意思是Java事务API,是一个Java企业版的应用程序接口,在Java环境中,允许完成跨越多个XA资源的分布式事务。JTA是在Java社区过程下制定的规范。

目前开源的JTA实现有以下几个:

  • narayananarayanajboss下的一款开源的JTA
  • bitronixbitronix是一款开源的JTA,不过目前已没人维护
  • atomikosatomikos目前提供了商业版本的维护,但其社区版仍然是开源的。
Name Description Pom
spring-boot-starter-jta-narayana 集成了JTA transactionsnarayana Pom
spring-boot-starter-jta-bitronix 集成了JTA transactionsbitronix Pom
spring-boot-starter-jta-atomikos 集成了JTA transactionsatomikos Pom

Template Engine

spring-boot-1.4.2.RELEASE内置支持的模板引擎有
thymeleafmustachegroovyfreemarkervelocity。不过从1.4将不再支持velocity

Name Description Pom
spring-boot-starter-thymeleaf 集成了spring-boot-starter-webthymeleaf模板引擎 Pom
spring-boot-starter-mustache 集成了spring-boot-starter-webmustache模板引擎 Pom
spring-boot-starter-groovy-templates 集成了spring-boot-starter-webgroovy-templates模板引擎 Pom
spring-boot-starter-freemarker 集成了spring-boot-starter-webfreemarker模板引擎 Pom
spring-boot-starter-velocity 集成了spring-boot-starter-webvelocity模板引擎 Pom

Logging

目前主流的Java日志框架有log4jlogbacklog4j2spring-boot集成了logbacklog4j2

Name Description Pom
spring-boot-starter-logging 集成logback Pom
spring-boot-starter-log4j2 集成log4j2 Pom

Test

目前主流的Java测试框架有JUnitHamcrestMockitospring-boot集成了这三者。

Name Description Pom
spring-boot-starter-test 集成了JUnitHamcrestMockito Pom

Security

spring-securityspring旗下的一个子项目,支持授权和认证,可以防止session fixation(会话固定)、clickjacking(点击劫持)、cross site request forgery(CSRF)(跨站请求伪造)等攻击。spring-boot集成了spring-security

Name Description Pom
spring-boot-starter-security 集成了spring-security Pom

MQ

JMSJava Message Service的缩写,意思是Java消息服务,是一个Java服务中关于面向消息中间件的API,用于在两个应用程序之间或分布式系统中发送消息,进行异步通信。JMS规范包括两种消息模式,点对点发布者/订阅者,支持同步异步的消息处理,支持面向事件的方法接收消息。目前主流的开源实现有Apache ActiveMQKafka

AMQPAdvanced Message Queuing Protocol的缩写,意思是高级消息队列协议,是一个异步消息传递所使用的应用层协议规范。作为线路层协议,而不是API(例如JMS),AMQP客户端能够无视消息的来源任意发送和接受信息。目前主流的开源实现有RabbitMQ

JMSAMQP的对比:

JMS AMQP
定义 JAVA API Protocol
跨语言
跨平台
消息模型 one to one and publish/subscriber direct, fanout, topic, headers
消息类型 text,map,byte,stream,object byte

spring-boot集成了ActiveMQRabbitMQ

Name Description Pom
spring-boot-starter-activemq 集成ActiveMQ Pom
spring-boot-starter-amqp 集成RabbitMQ Pom

Production Starters

Name Description Pom

参考

spring-boot-features-spring-application

引言

本文主要介绍spring-bootSpringApplication特性,对应的spring-boot版本均为1.4.2.RELEASE,官方文档地址为http://docs.spring.io/spring-boot/docs/1.4.2.RELEASE/reference/html/boot-features-spring-application.html

快速构建你的第一个SpringApplication

SpringApplication提供了一种最简单的方式来启动应用,那就是通过main函数,只需要一行代码就可以启动应用。

1
2
3
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

运行main函数,会输出如下信息

1
2
3
4
5
6
7
8
9
10
11
12
13
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.2.RELEASE)
2016-12-23 11:33:32.897 INFO 46716 --- [ main] org.felix.spring.boot.Application : Starting Applicationwith PID 46716
2016-12-23 11:33:35.251 INFO 46716 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-12-23 11:33:35.268 INFO 46716 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.6
2016-12-23 11:33:37.305 INFO 46716 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-12-23 11:33:37.312 INFO 46716 --- [ main] org.felix.spring.boot.Application : Started Application in 6.004 seconds (JVM running for 6.987)

这里省略了一些信息的输出,从这些输出的信息可以看到

  • Spring Boot的版本
  • Spring Boot内置了一个Apache Tomcat/8.5.6的Tomcat
  • 默认的启动端口为8080
  • 默认的日志输出级别为INFO
  • Spring Application启动的进程(PID)为46716

启动时失败

FailureAnalyzer

Spring Boot1.4版本之后新增了FailureAnalyzer接口,它可以拦截异常,并将其转换为更易读的诊断信息。比如当Spring Application试图使用已被占用的端口时,将显示如下信息

1
2
3
4
5
6
7
8
9
10
11
***************************
APPLICATION FAILED TO START
***************************
Description:
The Tomcat connector configured to listen on port 8196 failed to start. The port may already be in use or the connector may be misconfigured.
Action:
Verify the connector's configuration, identify and stop any process that's listening on port 8196, or configure this application to listen on another port.

Spring Boot-1.4.2-RELEASE版本内置了以下几个FailureAnalyzer

  • BeanCurrentlyInCreationFailureAnalyzer
  • BeanNotOfRequiredTypeFailureAnalyzer
  • BindFailureAnalyzer
  • ConnectorStartFailureAnalyzer
  • NoUniqueBeanDefinitionFailureAnalyzer
  • PortInUseFailureAnalyzer
  • ValidationExceptionFailureAnalyzer

你可以从spring-boot-1.4.2-RELEASE.jar里的META-INF/spring.factories找到上述几个FailureAnalyzer

FailureAnalyzer小结

  • Spring Application默认是开启FailureAnalyzer的,并没有提供关闭的配置
  • FailureAnalyzer的配置只能通过配置文件注入
  • 如果你没有为异常定义自己的FailureAnalyzer,你仍然可以通过--debug来打印诊断信息,比如java -jar myproject-0.0.1-SNAPSHOT.jar --debug

自定义Banner

自定义SpringApplication

如果你不喜欢默认的Spring Application,你当然可以自己去定义一个Spring Application,比如关闭Banner

1
2
3
4
5
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}

Spring Boot也提供了基于配置文件application.properties的形式来构建一个Spring Application。具体的用法可以参考Externalized Configuration

流式构建的API(Fluent builder API)

Spring Boot提供了SpringApplicationBuilder以流式的形式来构建Spring Application

1
2
3
4
5
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);

应用事件和监听器

除了通常的Spring框架的事件,比如ContextRefreshedEvent,一个SpringApplication还会发送一些额外的应用事件。

你不能使用@Bean去注册一个监听器去监听在ApplicationContext被创建之前触发的那些事件上。你可以通过SpringApplication.addListeners(…​)或者SpringApplicationBuilder.listeners(…​)来注册。
如果你想自动注册这些监听器不管应用以何种方式启动,你可以在你的工程下创建一个文件META-INF/spring.factories,然后引用以下配置

1
org.springframework.context.ApplicationListener=com.example.project.MyListener

当你的应用程序运行时,应用事件按下列顺序发送:

  1. ApplicationStartedEvent:启动时发送该事件
  2. ApplicationEnvironmentPreparedEvent:Environment加载完成,但是上下文未创建发送该事件
  3. ApplicationPreparedEvent:上下文加载完成,但是spring bean未加载完成发送该事件
  4. ApplicationReadyEvent:启动完成发送该事件,整个应用程序处于就绪状态
  5. ApplicationFailedEvent:启动时异常发送该事件

WebEnvironment

Spring Appication默认是开启Web Environment,你可以通过setWebEnvironment(false)来关闭它,比如正在使用SpringApplicationJUnit测试。

获取应用程序启动时的参数

如果你使用SpringApplication.run(Application.class,args)来启动一个Spring Application,然后你又希望你在自己定义的Bean里用到这些参数,那么你可以通过注入一个ApplicationArguments来获取,ApplicationArguments提供了各种各样的方式来获取参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.springframework.boot.*
import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
}
}

当然,Spring Boot会根据Environment来注册一个CommandLinePropertySource,你可以通过@Value来获取

使用ApplicationRunner或者CommandLineRunner

如果你想在Spring Application启动时运行自己的一些代码,你可以自己定义一个Bean,实现接口ApplicationRunner或者CommandLineRunnerSpring Application会在SpringApplication.run(…​)之前去调用他们。

ApplicationRunnerCommandLineRunner的区别在于ApplicationRunner使用了String... args作为参数,ApplicationRunner使用了ApplicationArguments作为参数。

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}

如果你定义了多个Runner,然后又希望他们是有序去执行的,两种方式供你选择

  • 实现接口org.springframework.core.Ordered
  • 使用注解org.springframework.core.annotation.Order

优雅退出

任何一个Spring Application都会向JVM注册一个Shutdown Hook以便ApplicationContextSpring Application退出的时候能够优雅的关闭。

  • 实现接口DisposableBean
  • 使用注解@PreDestroy
  • 实现接口org.springframework.boot.ExitCodeGenerator,在Spring Application退出的时候能返回自己定义的exit code

Admin功能