Spring Boot俨然已经成为Java Web的开发标准,但是使用上发现千人千面,这里整理了一些在使用Spring Boot使用中常见的情况,希望作为一个小小的Guideline来帮助项目中同事统一用法,也包含了一些小小的Best Practices。
可能内容并不太适合Spring Boot的初学者或者对Spring还很陌生的读者。
I. Prerequisites
我们项目中使用Spring Boot的基本准则是:
- 配置最小化,通用配置尽量采用Spring Boot的自动配置(auto configuration),通过Spring Boot推荐的方式来完成配置的自定义。
- 尽量采用Java-based配置的方式(这一点只是个人偏好而已)。
- 尽量采用Spring Boot推荐的包结构。
- 本系列采用的Spring Boot版本为:1.5.3.RELEASE;
- JDK 版本 1.8 or later;
- Maven 3.0+;
- 开发工具推荐 IntelliJ IDEA(Community版即可);
II. 依赖管理
Spring Boot推荐使用spring-boot-starter-parent
作为项目的POM的Parent,不过我们的项目推荐使用的是:
复制代码 io.spring.platform platform-bom Brussels-SR2
Spring IO Platform包含了Spring模块和大量的第三库版本(可以查看这些库的),都是经过测试可以完美工作的。
事实上,如果是查看一下,会发现他继承了spring-boot-starter-parent
,所以说一般情况下你基于Spring Boot的项目可以直接用Spring IO Platform作为parent。因为Spring IO Platform提供了spring-boot-starter-parent
的超集,包含了许多spring-boot-starter-parent
中没有提供的依赖,比如com.google.protobuf
等。
III. 选择合适的starter
应该是Spring Boot提供的最大便利了,其提供了某个feature所需依赖的配置和自动配置相关Bean的服务。例如spring-boot-starter-data-redis
,会帮我们自动引入jedis等依赖,并且提供开箱即用的RedisConnectionFactory
, StringRedisTemplate
, RedisTemplate
实例。
除了官方提供的starter,还有许多第三方starter能帮我们节省很大的精力,比如mybatis-spring-boot-starter
让我们不用再关心mybatis的依赖引入和配置,pagehelper-spring-boot-starter
让我们一行代码搞定翻页。
IV. 合理的Package Structure
假设我们的项目是一个中等项目,并没有采用流行的微服务架构,而是包含多个modules,例如:
└── service-lib //包含entity、dao、service等基础业务代码└── api //依赖于service-lib,提供REST API└── tasks //依赖于service-lib,运行一些Scheduled tasks复制代码
其中service-lib的包结构大致如下:
src/main/java/└── com └── bytecho └── sample └── lib ├── ServiceLibraryConfig.java ❶ ├── mappers ├── models ├── services └── utils复制代码
❶ ServiceLibraryConfig
内容:
@Configuration@EnableAsync@EnableCaching(proxyTargetClass = true)public class ServiceLibraryConfig { @Bean public RedisTemplate
api module包结构如下:
src/main/java/└── com └── bytecho └── sample ├── APIWebServer.java └── web ├── advices ├── controllers ├── ...复制代码
APIWebServer
的内容:
@SpringBootApplicationpublic class APIWebServer { public static void main( String[] args ) { SpringApplication.run(APIWebServer.class, args); }}复制代码
@SpringBootApplication
这个注解,我们都知道其等价于三个注解@Configuration
、@EnableAutoConfiguration
、@ComponentScan
,
APIWebServer
位于package:com.bytecho.sample
下,@ComponentScan
会帮助我们自动扫描这个包下所有的Component、Services以及Configuration,所以service-lib这个项目下所有的组件都会放到相应context里,不用我们再显式的去@Import(ServiceLibraryConfig.class)
,也不用再去声明component scan需要扫描的package路径。 V. 配置文件及Profiles
推荐使用Multi-profile YAML documents,即各环境配置放在同一配置文件application.yml
中。
spring: profiles: active: dev datasource: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver hikari: connection-timeout: 10000 #10 sec maximum-pool-size: 15---spring: profiles: dev datasource: url: jdbc:mysql://127.0.0.1:3306/bytecho?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true username: bytecho password: bytecho111 redis: host: 127.0.0.1 port: 17500 password: bytecho111---spring: profiles: staging datasource: url: jdbc:mysql://10.10.11.11:3306/bytecho?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true username: bytecho_test password: bytecho_test redis: host: 10.10.11.11 port: 17500 password: bytecho_test---spring: profiles: production #省略复制代码
简单的项目这样做比较一目了然,启动的时候通过命令行参数指定当前profile:--spring.profiles.active=prod
VI. 日志处理
浩瀚的Java世界里有为数众多的Logging框架,于是勤劳的Java程序员们又发明了不同的Logging Facade代理底层的Logging框架来解耦(设计模式的使用真是炉火纯青)。
- Logging Facade: ,
- Logging Infrastructure: java.util.logging, ,
Spring Boot底层使用Commons Logging作为Facade。如果引入了starter(所有starter依赖于spring-boot-starter-logging),Spring Boot默认会使用底层日志框架为Logback。
简单的配置可以直接在application.properties
(application.yml
)中完成: logging.level.root=WARNlogging.level.org.springframework.web=DEBUGlogging.level.com.bytecho.sample=DEBUGlogging.file=/opt/logs/api.log复制代码
当然为了减小application.properties
的体积和更大的定制性,我们使用推荐的logback-spring.xml
来完成对Logback的配置,代码中使用SLF4J作为facade。
复制代码 ❶ ❷ ❸ ❹ ❺ ${LOG_FILE} ${LOG_FILE}.%d{yyyyMMdd} UTF-8 ${FILE_LOG_PATTERN}
❶ 这里引入Spring Boot自带的一些:默认的Log Pattern,一些第三方库默认的日志级别等;
❷ 注意这里${variable:-defaultValue}
的形式是Logback自己的,LOG_FILE来自于Spring Environment中的logging.file,你可以在application.properties中配置,Spring Boot帮你把该值放入了System properties,如果没有,取默认值/opt/logs/sample.log
;❸ 默认的console-appender,也可以参考这个文件内容自己来配置;❹和❺为Spring Boot对Logback的扩展,支持对不同profile采用不同的日志配置。