Spring Boot 其實(shí)是對(duì)Spring家族和一些常用組件的一個(gè)比較好的組合打包的方式,并將很多通用的配置都內(nèi)置了,如果不需要太多個(gè)性化配置,采用很少的配置就可以跑起來, 使得使用起來很方便,比如:
- 簡化配置
- 結(jié)合spring data jpa 數(shù)據(jù)庫操作簡便
- RestController 返回結(jié)果自動(dòng)轉(zhuǎn)換 json
- 直接運(yùn)行jar的方式(內(nèi)嵌tomcat等容器) 部署方便,和docker很容易結(jié)合
- ……
開始
參考 quick start
pom.xml里配置parent 和核心的幾個(gè)依賴:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
實(shí)際上spring-boot-starter-web只是一個(gè)pom文件, 里面預(yù)置好了關(guān)鍵的依賴, 如spring context、spring mvc、log等:

配置
官網(wǎng)資料 Properties & configuration
屬性獲取
默認(rèn)的配置文件是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中配置項(xiàng)名字的前綴如: sys1.url, Config類中的屬性名url和配置文件中的后部分一致, 實(shí)現(xiàn)自動(dòng)注入。
除了prefix,ConfigurationProperties也可以有locations指定默認(rèn)配置文件外的其他配置文件
application.properties有些配置項(xiàng)會(huì)被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
多環(huán)境
測試、開發(fā)和線上的配置分開,并可以在運(yùn)行時(shí)指定配置, 采用profiles的方式。
啟動(dòng)時(shí)可指定profile: java -jar -Dspring.profiles.active=production demo.jar
properties文件配置
使用properties配置的, 公共配置放application.properties, 環(huán)境配置放 application-env.properties,如application-dev.properties, application.properties可指定默認(rèn)激活的環(huán)境:spring.profiles.active= dev, 使用application-dev.properties中的配置
yaml文件配置
可將所有環(huán)境配置放application.yml中, 通過 ---分隔每個(gè)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
# 默認(rèn)激活的環(huán)境配置
spring:
profiles.active: dev
---
# 線上環(huán)境配置
spring:
profiles: online
server:
port: 80
logging:
path: /home/logs/sys1/
level: info
cas:
serviceUrl: http://site.online/
---
#測試環(huán)境配置
spring:
profiles: test
server:
port: 8080
logging:
file: sys1.log
level: debug
cas:
serviceUrl: http://site.test/
---
#開發(fā)環(huán)境配置
spring:
profiles: dev
server:
port: 8080
logging:
file: sys1.log
level: debug
cas:
serviceUrl: http://site.dev/
日志
spring boot默認(rèn)采用logback, 可在application.properties里配置。 啟動(dòng)時(shí)還可以指定日志級(jí)別 java -jar myapp.jar --debug
靜態(tài)頁面
靜態(tài)資源如html js image等放到(或打包時(shí)發(fā)布到)這些目錄:
/resources 、 /META-INF/resources、 /public 、 /static
如:習(xí)慣放在webapp下的,在pom.xml中配置發(fā)布到/public下
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
<targetPath>/public</targetPath>
</resource>
</resources>
</build>
前端訪問這些靜態(tài)資源時(shí) 路徑當(dāng)作是在/下, 如/public/index.html,訪問時(shí)用/index.html。
見 stackoverflow:Spring Boot not serving static content
數(shù)據(jù)庫
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.15</version>
</dependency>
可在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,則會(huì)自動(dòng)使用tomcat-jdbc連接池
Tomcat 的 JDBC 連接池
最后一句配置SlowQueryReport可在數(shù)據(jù)庫查詢超過1000毫秒時(shí)打印慢查日志。
spring.datasource.test-while-idle=true spring.datasource.time-between-eviction-runs-millis= 3600000 在空閑時(shí) 每個(gè)1小時(shí) 訪問一下數(shù)據(jù)庫,避免連接池中的連接因超時(shí)而失效, 見 stackoverflow:Spring Boot JPA - configuring auto reconnect
Spring Data JPA
spring data jpa 是基于Hibernate的, 通過Entity可自動(dòng)創(chuàng)建數(shù)據(jù)表,甚至關(guān)聯(lián)表(如User 和 Role的關(guān)聯(lián)表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<Role> roles = new HashSet<Role>();
// get set 方法省略
}
Dao層只要繼承JpaRepository 就已經(jīng)有了基本的增刪查改功能, 需要定制SQL的可以通過@Query注解完成,見 Using @Query
public interface UserDao extends JpaRepository <User, Integer>{
User findByLoginName(String loginName);
void deleteByLoginName(String loginname);
}
public interface RoleDao extends JpaRepository<Role, Integer> {
Role findByName(String loginName);
@Query("SELECT r FROM Role r WHERE r.id IN (?1)")
List<Role> findRolesByIds(List<Integer> ids);
}
并可在其他類中直接自動(dòng)注入,如@Autowired private UserDao userDao;, 接口是不能實(shí)例化的, 這里應(yīng)該是框架會(huì)根據(jù)接口定義自動(dòng)創(chuàng)建一個(gè)代理類, 注入的其實(shí)是代理類。
Spring MVC
在以往后端返回?cái)?shù)據(jù)時(shí), 需要自己采用json庫,將pojo轉(zhuǎn)換為json字符串輸出到前端, spring boot 默認(rèn)給做了這個(gè)事情:
@RestController
@RequestMapping("admin")
public class AdminController {
Logger log = LoggerFactory.getLogger(AdminController.class);
@Autowired private UserDao userDao;
@RequestMapping(value = "users", method = RequestMethod.GET)
public List<User> getUsers() {
return new userDao.findAll();
}
}
訪問 /admin/users 直接返回:
[
{
"id": 19,
"loginName": "123456@qq.com",
"roles": [
{ "id": 3, "name": "ADMIN" },
{ "id": 2, "name": "OPS" }
]
}
]
測試
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
spring-boot-starter-test 里引入了junit等。
測試類上增加注解:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = App.class)
然后就可以使用junit的 @Before @After 和 @Test 等注解來寫測試方法了。
熱部署
在開發(fā)時(shí),修改代碼,IDE觸發(fā)自動(dòng)編譯后, 應(yīng)該是Spring boot的buildspring-boot-maven-plugin自動(dòng)觸發(fā)了自動(dòng)reload類。
目前可能是我IDE設(shè)置的問題, 每次修改后還得右鍵Recompile一下。
也有說使用spring-boot-devtools等依賴來完成的。
官網(wǎng)資料 using-boot-hot-swapping
Spring Security 和 CAS 集成
示例 github: demo-spring-security-cas
官網(wǎng)說明:spring io: CAS Authentication, 說明中是基于xml配置的, 要轉(zhuǎn)換為Spring boot的注解配置。