在令和时代阅读《Spring入门》和《Spring彻底入门》时需要注意的N个事项
关于这篇文章的内容
正如我在每个场合都提到的那样,即使是在迎接2020年的当前时刻,可靠的与Spring相关的书籍只有以下两本。
-
- Spring徹底入門
- 改訂新版Spring入門
以下的两本书籍都是非常好的书,但它们都在2016年发布,当前对应的Spring版本已过时,只支持4.2版本。
2019年底最新版本是Spring 5.2。在本文中,将介绍在读令和时特别需要注意的几点关注事项。
请查阅GitHub的Wiki以获取4.x到5.x版本的所有差异。
应使用JDK 8或更高版本。
从Spring 5.0开始,JDK的基线版本已经更新至8(而Spring 4则基于JDK 6)。我认为现在想要使用Spring的人不会再考虑使用JDK 6或7了…
在Spring 5.2版本中,支持JDK版本为14。请参阅GitHub的Wiki获取JDK和Spring版本的详细对应信息。
应该使用构造函数注入+@Autowired注解来代替字段注入,并且可以简写为省略写法。
从Spring 4.2之前开始,依赖注入的方法有三种。
@Component
public class Hoge {
@Autowired
Fuga fuga;
}
@Component
public class Hoge {
private Fuga fuga;
@Autowired
public void setFuga(Fuga fuga) {
this.fuga = fuga;
}
}
@Component
public class Hoge {
private final Fuga fuga;
@Autowired
public Hoge(Fuga fuga) {
this.fuga = fuga;
}
}
在书籍中经常使用的是字段注入。可能是因为它的描述量最少(可能也是因为纸面的限制)。
从Spring 4.3版本开始,如果类内部只有一个构造函数,则可以省略使用@Autowired注解。
@Component
public class Hoge {
private final Fuga fuga;
// コンストラクタが1つしか無いので@Autowiredは省略可能!
public Hoge(Fuga fuga) {
this.fuga = fuga;
}
}
由于可以使类变为不可变的,所以请尽可能使用构造器注入。
应使用 @GetMapping 等而非 @RequestMapping
想要在Spring MVC中编写控制器类和方法,可以使用 @RequestMapping。
@Controller
@RequestMapping("/hoge")
public class HogeController {
@RequestMapping(value = "/index", method = RequestMethod.GET)
public String index() {
return "index";
}
}
从Spring 4.3版本开始,引入了各种HTTP请求方法的注解,例如@GetMapping和@PostMapping。这种写法非常简洁方便!
@Controller
@RequestMapping("/hoge") // ここは@RequestMappingのままでOK
public class HogeController {
@GetMapping("/index") // @XxxMappingを使う!
public String index() {
return "index";
}
}
应该使用Thymeleaf 3以HTML格式编写(不是XHTML)。
在图书中使用的是Thymeleaf 2。要在Thymeleaf 2中写出界面,需要使用XHTML格式。
如果添加库,即使使用2,也可以以HTML格式编写。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>画面</title>
</head>
<body>
<form action="index.html" th:action="@{findByFirstName}">
名キーワード:<input type="text" name="firstName" />
<input type="submit" value="検索" />
</form>
...
在Thymeleaf 3中,默认可以以HTML格式编写。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>画面</title>
</head>
<body>
<form action="index.html" th:action="@{findByFirstName}">
名キーワード:<input type="text" name="firstName">
<input type="submit" value="検索">
</form>
...
忘记了“/”这个步骤后,再也不会发生运行时异常了,真是太好了!
应该使用WebMvcConfigurer接口而不是WebMvcConfigurerAdapter类。
在Spring 4.3之前,在创建Spring MVC相关的Java配置时,经常会继承WebMvcConfigurerAdapter类。
@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
...
}
...
}
从Spring 5.0开始,这个类已被标记为不推荐使用,并建议使用该类实现的WebMvcConfigurer接口。
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
...
}
...
}
WebMvcConfigurerAdapter 类是一个实现了 WebMvcConfigurer 接口的类,它以空的状态覆盖了所有方法的实现。由于它基于 Java 8,WebMvcConfigurer 接口的所有方法都变成了空实现的默认方法。因此,WebMvcConfigurerAdapter 类已被弃用,因为它已经完成了它的使命。
WebMvcConfigurer 的源代码
应该使用Bean Validation的@NotBlank而不是Hibernate Validator的@NotBlank。
在Spring 5对Java EE 8进行了支持后,Bean Validation的版本从1.x升级到2.0(Hibernate Validator 6.0及以上版本)。
使用Spring 5也可以使用Bean Validation 1.x,但基本上建议使用最新版本。
在Bean Validation 2.0版本中,新增了一些新的约束注解。其中部分注解是Hibernate Validator自有的注解,现已纳入了Bean Validation的标准规范中。具体来说,下列注解属于这一类(全部来自javax.validation.constraints包)。
-
- @NotEmpty
-
- @NotBlank
- @Email
随着这一变化,Hibernate Validator中的独有注解 @NotBlank、 @NotEmpty和 @Email(都在org.hibernate.validator.constraints包中)已被标注为不推荐使用。
需要注意的是,Spring Data的CrudRepository不兼容。
自 Spring Data 2.x 起,CrudRepository 中定义的方法名称、返回值等发生了变化。
在中国,只需要一种选择重新表述以下内容:变更点包括对java.util.Optional的支持以及方法名称的更改等。
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S entity);
<S extends T> Iterable<S> save(Iterable<S> entities);
T findOne(ID id);
boolean exists(ID id);
Iterable<T> findAll();
Iterable<T> findAll(Iterable<ID> ids);
long count();
void delete(ID id);
void delete(T entity);
void delete(Iterable<? extends T> entities);
void deleteAll();
}
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity);
<S extends T> Iterable<S> saveAll(Iterable<S> entities);
Optional<T> findById(ID id);
boolean existsById(ID id);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> ids);
long count();
void deleteById(ID id);
void delete(T entity);
void deleteAll(Iterable<? extends T> entities);
void deleteAll();
}
在使用Spring Security时,务必明确地设置PasswordEncoder。
在Spring Security 4以前,如果没有明确指定PasswordEncoder,则不会对密码进行哈希化处理。
在Spring Security 5及之后的版本中,如果没有明确指定PasswordEncoder,将使用DelegatingPasswordEncoder。它会根据存储在数据库等位置的密码前缀,来选择合适的PasswordEncoder进行处理。

我认为在生产环境中没有人会没有指定PasswordEncoder(希望如此)。但是,我想在学习用的代码中为了简化可能会出现没有指定的情况。从Spring Security 5.x开始,请务必指定PasswordEncoder。只需将PasswordEncoder定义为Bean即可。当然,还请使用相同的算法将保存在数据库等中的密码进行哈希处理。
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
由于Spring Boot的内容已经发生了很大变化,请注意。
关于Spring Boot 1.x转2.x来说,变化太多以至于无法一一列举,哈哈哈。
仅需一个选项,请将以下内容用中文进行表述:
即使匆忙想起来,
-
- 各種ライブラリのアップデート
Spring 4.x -> 5.x
Spring Data 1.x -> 2.x
Spring Security 4.x -> 5.x
Thymeleaf 2 -> 3
Hibernate -> 5.4
Jackson -> 2.10
Hibernate Validator 5.x -> 6.1
Flyway 4 -> 6
JDK 8対応
thymeleaf-extras-java8time追加済み
jackson-datatype-jdk8など追加済み
セキュリティの簡素化
セキュリティ関連のプロパティがほとんど削除された
Actuatorの改良
内部アーキテクチャの抜本的変更
認証・認可の変更
Micrometerの追加
プロパティの変更
プロパティのリネーム
各種プロパティの名前が大幅に変更
可能会有很多其他的东西。
2020年2月12日附注
我会附上在JSUG研讨会上发表的资料。两份资料都非常珍贵,务必阅读一下!
刚刚在会议上的幻灯片
-
- 決済サービスのSpring Bootのバージョンを2系に上げた話(@b1a9idps)
- Spring Boot 1.5→2.1バージョンアップを経験して分かったハマりどころ(@kawakawaryuryu)
@b1a9idps さん的博客目录
-
- 決済サービスのSpring Bootのバージョンを2系に上げた
-
- Flyway 3.x -> 5.xに上げた
-
- Spring Boot 1.5.xから2.0.xに上げた ~Spring Web編~
-
- Spring Boot 1.5.xから2.0.xに上げた ~Spring Data編~
- Spring Boot 1.5.xから2.0.xに上げた ~Spring Test編~
附加说明2020年10月16日
在Spring Boot 2.3版本及更高版本中,spring-boot-starter-web中不再包含Hibernate Validator(发行说明)。
如果想要使用Hibernate Validator,需要添加spring-boot-starter-validation。
(2022-06-16追記)Spring Security的WebSecurityConfigurerAdapter已被标记为不推荐使用。
安全设置的编写方式已经发生了重大变化。请参考下文的文章了解详细情况。
总结
一旦我想起来,就会逐步添加补充内容。