Spring Boot 其实是对Spring家族和一些常用组件的一个比较好的组合打包的方式,并将很多通用的配置都内置了,如果不需要太多个性化配置,采用很少的配置就可以跑起来, 使得使用起来很方便,比如:
- 简化配置
- 结合spring data jpa 数据库操作简便
- RestController 返回结果自动转换 json
- 直接运行jar的方式(内嵌tomcat等容器) 部署方便,和docker很容易结合
- ……
开始
参考 quick start
pom.xml
里配置parent 和核心的几个依赖:
org.springframework.boot
spring-boot-starter-parent
1.4.2.RELEASE
org.springframework.boot
spring-boot-starter-web
实际上spring-boot-starter-web
只是一个pom文件, 里面预置好了关键的依赖, 如spring context、spring mvc、log等:
配置
官网资料 Properties & configuration
属性获取
默认的配置文件是application.properties
或 application.yml
。
@Value
@Value("${sys1.url}") String url;
Environment
@Autowired private Environment env;
String url = env.getProperty("sys1.url")
ConfigurationProperties
@ConfigurationProperties(prefix = "sys1")
class Config {
private String url;
// url 的 set get 方法 ...
}
ConfigurationProperties的prefix指定在application.properties中配置项名字的前缀如: sys1.url, Config类中的属性名url和配置文件中的后部分一致, 实现自动注入。
除了prefix,ConfigurationProperties也可以有locations
指定默认配置文件外的其他配置文件
application.properties有些配置项会被spring boot读取,如:
server.port = 8080
server.session-timeout = 7200
# log
logging.file= application.log
logging.level.org.springframework .security.cas = INFO
logging.level.com.my.cloud.vodlivemgr.* = DEBUG
# db
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&autoReconnectForPools=true
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
多环境
测试、开发和线上的配置分开,并可以在运行时指定配置, 采用profiles的方式。
启动时可指定profile: java -jar -Dspring.profiles.active=production demo.jar
properties文件配置
使用properties配置的, 公共配置放application.properties, 环境配置放 application-env
.properties,如application-dev.properties, application.properties可指定默认激活的环境:spring.profiles.active= dev
, 使用application-dev.properties中的配置
yaml文件配置
可将所有环境配置放application.yml中
, 通过 ---
分隔每个profile。
# 公共配置
server:
tomcat:
uri-encoding: utf-8
max-threads: 1024
access_log_enabled: true
session:
timeout: 60
cas:
casServerLoginUrl: https://sso.mysit/login
casServerUrlPrefix: https://sso.mysit/cas
# 默认激活的环境配置
spring:
profiles.active: dev
---
# 线上环境配置
spring:
profiles: online
server:
port: 80
logging:
path: /home/logs/sys1/
level: info
cas:
serviceUrl: http://site.online/
---
#测试环境配置
spring:
profiles: test
server:
port: 8080
logging:
file: sys1.log
level: debug
cas:
serviceUrl: http://site.test/
---
#开发环境配置
spring:
profiles: dev
server:
port: 8080
logging:
file: sys1.log
level: debug
cas:
serviceUrl: http://site.dev/
日志
spring boot默认采用logback, 可在application.properties里配置。 启动时还可以指定日志级别 java -jar myapp.jar --debug
静态页面
静态资源如html js image等放到(或打包时发布到)这些目录:
/resources 、 /META-INF/resources、 /public 、 /static
如:习惯放在webapp下的,在pom.xml中配置发布到/public下
src/main/webapp
/public
前端访问这些静态资源时 路径当作是在/下, 如/public/index.html,访问时用/index.html。
见 stackoverflow:Spring Boot not serving static content
数据库
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
5.1.15
可在application.properties里配置:
# db
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=utf8
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.validation-query=select 1
spring.datasource.test-while-idle=true
spring.datasource.time-between-eviction-runs-millis= 3600000
spring.datasource.max-active= 10
spring.datasource.min-idle= 1
spring.datasource.max-idle= 5
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.datasource.jdbc-interceptors=ConnectionState;SlowQueryReport(threshold=1000)
pom引用了spring-boot-starter-data-jpa
,则会自动使用tomcat-jdbc连接池
Tomcat 的 JDBC 连接池
最后一句配置SlowQueryReport
可在数据库查询超过1000毫秒时打印慢查日志。
spring.datasource.test-while-idle=true
spring.datasource.time-between-eviction-runs-millis= 3600000
在空闲时 每个1小时 访问一下数据库,避免连接池中的连接因超时而失效, 见 stackoverflow:Spring Boot JPA - configuring auto reconnect
Spring Data JPA
spring data jpa 是基于Hibernate的, 通过Entity
可自动创建数据表,甚至关联表(如User 和 Role的关联表user_role)
@Entity
public class User {
@Id
@GeneratedValue
private int id;
@Column(unique = true, nullable = false)
private String loginName;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set roles = new HashSet();
// get set 方法省略
}
Dao层只要继承JpaRepository
就已经有了基本的增删查改功能, 需要定制SQL的可以通过@Query
注解完成,见 Using @Query
public interface UserDao extends JpaRepository {
User findByLoginName(String loginName);
void deleteByLoginName(String loginname);
}
public interface RoleDao extends JpaRepository {
Role findByName(String loginName);
@Query("SELECT r FROM Role r WHERE r.id IN (?1)")
List findRolesByIds(List ids);
}
并可在其他类中直接自动注入,如@Autowired private UserDao userDao;
, 接口是不能实例化的, 这里应该是框架会根据接口定义自动创建一个代理类, 注入的其实是代理类。
Spring MVC
在以往后端返回数据时, 需要自己采用json库,将pojo转换为json字符串输出到前端, spring boot 默认给做了这个事情:
@RestController
@RequestMapping("admin")
public class AdminController {
Logger log = LoggerFactory.getLogger(AdminController.class);
@Autowired private UserDao userDao;
@RequestMapping(value = "users", method = RequestMethod.GET)
public List getUsers() {
return new userDao.findAll();
}
}
访问 /admin/users 直接返回:
[
{
"id": 19,
"loginName": "[email protected]",
"roles": [
{ "id": 3, "name": "ADMIN" },
{ "id": 2, "name": "OPS" }
]
}
]
测试
org.springframework.boot
spring-boot-starter-test
spring-boot-starter-test 里引入了junit等。
测试类上增加注解:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = App.class)
然后就可以使用junit的 @Before @After 和 @Test 等注解来写测试方法了。
热部署
在开发时,修改代码,IDE触发自动编译后, 应该是Spring boot的buildspring-boot-maven-plugin
自动触发了自动reload类。
目前可能是我IDE设置的问题, 每次修改后还得右键Recompile
一下。
也有说使用spring-boot-devtools
等依赖来完成的。
官网资料 using-boot-hot-swapping
Spring Security 和 CAS 集成
示例 github: demo-spring-security-cas
官网说明:spring io: CAS Authentication, 说明中是基于xml配置的, 要转换为Spring boot的注解配置。