この記事について
事ある度に書いたり言ったりしている通り、2020年を迎えようとしている現在でも、信頼できるSpring関連書籍は下記の2冊しかありません。
2冊(以下「書籍」)とも超良書なのですが、どちらもリリースされたのが2016年で、対応しているSpringのバージョンが4.2と古くなっています。
2019年末時点での最新版はSpring 5.2です。この記事では、上記書籍を令和の今読む際、特に気をつけるべき点をいくつか紹介していきます。
4.x->5.xの差分すべてについては、GitHubのWikiを確認してください。
JDKは8以上を使うべし
Spring 5.0以降から、JDKのベースラインが8になりました(Spring 4はJDK 6ベース)。今からSpringを使おうと言う人が、JDK 6とか7を使おうとはしないと思いますが・・・。
Spring 5.2では、JDK 14までサポートされます。JDKとSpringのバージョン対応の詳細はGitHubのWikiを参照してください。
フィールドインジェクションではなくコンストラクタインジェクション+ @Autowired
省略で書くべし
Spring 4.2以前から、DIの方法は3つありました。
@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から、クラス内にコンストラクタがただ1つしかない場合は、 @Autowired
が省略可能になりました。
@Component
public class Hoge {
private final Fuga fuga;
// コンストラクタが1つしか無いので@Autowiredは省略可能!
public Hoge(Fuga fuga) {
this.fuga = fuga;
}
}
クラスをイミュータブルにできるので、可能な限りコンストラクタインジェクションを使いましょう。
@RequestMapping
ではなく @GetMapping
などを使うべし
Spring MVCでコントローラークラス・メソッドを書くには @RequestMapping
を使います。
@Controller
@RequestMapping("/hoge")
public class HogeController {
@RequestMapping(value = "/index", method = RequestMethod.GET)
public String index() {
return "index";
}
}
Spring 4.3から、 @GetMapping
・ @PostMapping
など各HTTPリクエストメソッドごとのアノテーションが導入されました。とても短く書けていいですね!
@Controller
@RequestMapping("/hoge") // ここは@RequestMappingのままでOK
public class HogeController {
@GetMapping("/index") // @XxxMappingを使う!
public String index() {
return "index";
}
}
Thymeleaf 3を使いHTML形式で書くべし(not 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>
...
/
を忘れて実行時例外、なんてことが無くなって嬉しいですね!
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
が使われるようになりました。これは、DBなどに保存されているパスワードのプレフィックスを読んで、適切な PasswordEncoder
に処理を委譲するものです。
本番環境で PasswordEncoder
を指定していない人はいないと思います(そう信じたい)。しかし、勉強用のコードでは簡略化のために指定しないことはあったかと思います。Spring Security 5.x以降では、必ず指定しましょう。 PasswordEncoder
をBean定義すればOKです。もちろん、DBなどに保存されているパスワードも同じアルゴリズムの PasswordEncoder
でハッシュ化してください。
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Spring Bootの内容はだいぶ変わっているので注意すべし
Spring Boot 1.x->2.xについては、変更点が多すぎて書ききれませんw
パッと思いつくだけでも、
- 各種ライブラリのアップデート
- 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の追加
- プロパティの変更
- プロパティのリネーム
- 各種プロパティの名前が大幅に変更
・・・などなど。他にもいっぱいあるかも。
まとめ
思い出したら順次追記していきます。