Spring Boot Features(Part Ⅱ)

2017-08-10
Spring Framework

本篇继续针对上一篇文章对spring boot 未介绍完的feature进行补充。

Profiles

用过maven都知道,maven中有个profiles的设置。

profile一个非常重要的特性就是它可以根据不同的环境来激活,比如说根据操作系统的不同激活不同的profile,也可以根据jdk版本的不同激活不同的profile.

1
2
3
4
5
6
<profiles>
<profile>
<id>profileTest1</id>
<jdk>1.5</jdk>
</profile>
<profiles>

上面的配置就是当JDK版本为1.5的时候激活profileTest1。
spring boot也提供这么一种机制。在特定的环境下使用特定的配置。

1
2
3
4
5
6
7
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}

上面的配置就是在production环境下生效。通常在application.properties这个文件下配置spring.profiles.active=xxx属性来指定不同的profile。当然使用命令行也是可以的。

其实这个feature不算什么特性,很一般。

Logging

spring boot 内部的日志是使用的Common Logging,但是也提供很多其他的实现。默认还提供JUL、Log4J和Logback。

日志输出文本的颜色是可以设置的,假如控制台支持ANSI的话,然而我觉得并没卵用。默认情况下,日志只会输出到控制台,不会输出到文件。加入要输出到文件就需要在同样在application.properties文件中配置一下这几个属性了:logging.file logging.path。文件名不写的话默认为spring.log,路径不写的话默认在当前路径下。日志文件到10m的时候就回重新生成一个新的文件。

给日志设置级别就不多提了,都是很老掉牙的东西了。

1
2
3
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

自定义日志组件也是比较方便的,每个日志框架都有所不同嘛。spring boot提供这种热插拔式的配置。在配置文件中指定logging.config的值即可。这个属性代表着日志配置文件的位置。不同的日志系统有不同的配置文件。

  • logback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy是logback的。
  • log4j2-spring.xml, log4j2.xml是log4j2的。
  • logging.properties是JUL的。
    日志系统没什么可说的,对我而言,使用默认的就完事儿了。

基本上核心feature全部梳理完了。接下来看看Web Applications Features。

MVC

spring boot也适合web开发,使用spring-boot-starter-web模块很快就能搭建一个HTTP应用。
使用过Spring MVC的开发者来讲,这个feature一点都不新鲜。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RestController
@RequestMapping(value="/users")
public class MyRestController {
@RequestMapping(value="/{user}", method=RequestMethod.GET)
public User getUser(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
List<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}
}

这个栗子使用@RestController注解来返回JSON数据。
还有很多更详细的内容,可以参见spring framework 官方文档

Working with SQL databases

spring boot中对数据库的支持可以说是爽翻天。

首先得创建一个数据源,废话不多说:

1
2
3
4
5
@Bean
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() {
return new FancyDataSource();
}

1
2
3
app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30

意思就是这么个意思,配置方式多种多样。不仅仅可以支持外部数据库,内存数据库也是支持的。例如H2、HSQL和Derby,在spring boot中只需要提供一个依赖她就能自动配置,就是这么厉害。

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>

在对外部数据库的连接管理中,spring boot使用的是池化的数据源。对于使用何种池化方式,策略是这样的:Tomcat的连接池>HikariCP>DBCP(不推荐,因为没人去维护了)>DBCP2。

1
2
3
4
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

其中的url是一定要写的,不然的话spring boot去自动去配置内嵌的数据库了。driver可以不指定,因为可以通过url去判断driver。

说完数据源,再聊聊JdbcTemplate。这个东西在spring boot中用起来是非常爽,直接就能用。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
public class MyBean {
private final JdbcTemplate jdbcTemplate;
@Autowired
public MyBean(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// ...
}

仅此而已!

关于spring data和JPA 的介绍也没有多解释,文档说很多细节让我们去这里看看,看来还是比较复杂。

在传统的JPA中entity需要在persistence.xml中定义。但在spring boot中不需要这么麻烦,因为她能帮你扫描到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Entity
public class City implements Serializable {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
// ... additional members, often include @OneToMany mappings
protected City() {
// no-args constructor required by JPA spec
// this one is protected since it shouldn't be used directly
}
public City(String name, String state) {
this.name = name;
this.country = country;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
// ... etc
}

Spring Data JPA Repositories是一个好东西,JPA查询可以根据你方法的名字来。举个栗子,CityRepository接口定义一个findAllByState(String state)方法,你传一个state条件它就能查出来。

然而这仅仅只是一小部分,文档有句话细思极恐:

We have barely scratched the surface of Spring Data JPA.

spring boot对NoSQL也有支持。像MongoBD、Neo4J、Elasticsearch、Solr、Redis、 Gemfire、Cassandra、Couchbase 和LDAP。

Redis:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
public class MyBean {
private StringRedisTemplate template;
@Autowired
public MyBean(StringRedisTemplate template) {
this.template = template;
}
// ...
}

使用redis除了添加spring-boot-starter-data-redis依赖外,想用的话如上面代码一样简单。

MongoDB:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component
public class MyBean {
private final MongoDbFactory mongo;
@Autowired
public MyBean(MongoDbFactory mongo) {
this.mongo = mongo;
}
// ...
public void example() {
DB db = mongo.getDb();
// ...
}
}

mongodb同样也是如此,假如你的mongoDB采用分片的话,这样指定url就行:

1
spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test

如果使用的是2.x的版本,这样去配置:

1
2
spring.data.mongodb.host=mongoserver
spring.data.mongodb.port=27017

MongoTemplate用起来更加方便:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
public class MyBean {
private final MongoTemplate mongoTemplate;
@Autowired
public MyBean(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
// ...
}

其他的文档中也没多去解释,丢了个链接让读者自己去看。所以这里也不多去关注了。需要的时候再整理。

spring boot也提供对JMS的支持,这也算是一个feature吧。

JMS在Java中只定义了一些接口,具体实现还是依赖各个厂商。其中ActiveMQ就是一个JMS的标准实现,spring boot对其有比较好的支持。

同样的,只需要添加spring-boot-starter-activemq依赖,spring boot就能帮你自动去配置,当然少不了最基本的配置:

1
2
3
spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret

当然使用连接池也是可以的,添加这个依赖即可:org.apache.activemq:activemq-pool,同时做如下配置:

1
2
spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50

至于具体怎么去使用这里不再详细描述,使用到的时候再去这里翻翻文档看看。

Testing

对于一个框架来讲,测试一定是少不了的。spring boot提供了很多工具而注解来帮助开发者测试代码。有两个模块需要依赖:spring-boot-testspring-boot-test-autoconfigure。前者提供基础支持,后者提供自动配置。许多开发者只会选择前者,前者提供JUnit、AssertJ、Hamcrest及其他有用的工具包。

当你添加spring-boot-starter-test依赖时,你会发现很多库被添加进来了:

  • JUnit
  • Spring Test
  • AssertJ
  • Hamcrest
  • Mockito
  • JSONassert
  • JsonPath
    依赖注入的一个最大的好处就是让单元测试变得更简单。在spring framework的测试框架中,常常使用@ContextConfiguration(classes=…​)这样的配置,或者在你的测试中使用嵌套的@Configuration类。在spring boot中不需要这么麻烦,@*Test会自动去找你的配置。

在某些情况下,我们不需要自动去找测试的配置,我们可以自己手动指定配置:

1
2
3
4
5
6
7
8
9
10
11
@RunWith(SpringRunner.class)
@SpringBootTest
@Import(MyTestsConfiguration.class)
public class MyTests {
@Test
public void exampleTest() {
...
}
}

至于其他内容都没什么可讲的,无非就是一些annotation的使用。

总结

spring boot的一些比较有意思的feature基本上都梳理一遍了,当然也有许多没有很具体描述的地方。整个篇幅太长太多,很多细节的地方也没有很注意到,有些表述和文字组织还是非常欠缺,这都是自己对英文版的技术文档拿捏不是很准造成的。我想我整理的东西也只有我自己能看懂了。当然目前只是一个profile,很多坑还需要自己去踩的,只能在以后的工作及学习中慢慢总结,我想没有谁是仅仅通过看了一下文档就能写出漂亮的代码来吧。

接下来spring boot系列内容可能就更全面,具体整理哪些东西以后想到在说。毕竟这次的feature只是试试水。我也希望我对英文技术文档的理解有更加质的提升。


留言: