Spring Boot 总结

Spring Boot 其实是对Spring家族和一些常用组件的一个比较好的组合打包的方式,并将很多通用的配置都内置了,如果不需要太多个性化配置,采用很少的配置就可以跑起来, 使得使用起来很方便,比如:

  • 简化配置
  • 结合spring data jpa 数据库操作简便
  • RestController 返回结果自动转换 json
  • 直接运行jar的方式(内嵌tomcat等容器) 部署方便,和docker很容易结合
  • ……

开始

参考 quick start
pom.xml里配置parent 和核心的几个依赖:

 <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>

实际上spring-boot-starter-web只是一个pom文件, 里面预置好了关键的依赖, 如spring context、spring mvc、log等:

spring-boot-starter-web包含的依赖

配置

官网资料 Properties & configuration

属性获取

默认的配置文件是application.propertiesapplication.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下

<build>
    <resources>
        <resource>
            <directory>src/main/webapp</directory>
            <targetPath>/public</targetPath>
        </resource>
     </resources>
</build>

前端访问这些静态资源时 路径当作是在/下, 如/public/index.html,访问时用/index.html。
stackoverflow:Spring Boot not serving static content

数据库

<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,则会自动使用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<Role> roles = new HashSet<Role>();
    // get set 方法省略
}

Dao层只要继承JpaRepository 就已经有了基本的增删查改功能, 需要定制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);
}

并可在其他类中直接自动注入,如@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<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 等注解来写测试方法了。

热部署

在开发时,修改代码,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的注解配置。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容