Springの@Autowiredでインターフェースを指定するのはなんでなの
Javaのアノテーションなんもわからん
Spring解体新書
速習系の書籍なので、書籍の通りやればWebアプリケーションは完成します。
完成するんですが、私の性格が災いしており、理解できないところがあるとそのままにできなくて一生進みません。
いま見ている本はセクション名の通りこれです。コンパクトにまとまっていて、手早くSpring Bootに触れるには、いい本であると思います。
なぜか@Autowired
で実装側のクラスでなくインターフェースを指定している
本の中では、Userオブジェクトに対するDB処理を実装するのに(MVCに則り?)層別に管理しています。
上から順番に、
- ユーザ ーの
/home
へのリクエストを受け取って、 HomeController
がテンプレートエンジンを呼び出して、UserService
が表示するUser
に関する操作を受け持ち、UserDao
は@Autowired
されたinterfaceとして経由され、UserDaoJdbcImpl
に実際のDB操作が記述されており、- DB(H2)のデータに到達する
みたいな感じです。
Springでは、アノテーションに@Autowired
をつけるとフレームワークがよしなにインスタンス管理をしてくれます。便利ですね。
このときSpringがやっていることに対する私の理解は、以下です。
- まずアプリケーションのビルドを開始します。
- Springのフレームワークがプロジェクト内のソースコードを捜査してアノテーションが付与されている変数やらクラスやらを認知します。
- メソッド等の呼び出しに応じてSpringがインスタンスの生成・管理を行います。
- インターフェースが
@Autowired
されている場合、それを実装しているクラスのインスタンスが自動で紐づけられます。
よくわからないのは、なぜ実装しているクラスではなくインターフェース側に紐づけるかです。
実装しているクラスが単一の場合はわからんでもない
たとえば、今回の書籍の例ではUserService
内に@Autowired
で規定されたUserDao
インターフェースが あります。
@Service
public class UserService {
@Autowired
@Qualifier("UserDaoJdbcImpl2")
UserDao dao;
// 以下ではダメなのか
// UserDaoJdbcImpl2 dao;
このとき、@Qualifier
がない場合はインターフェースを経由するメリットがありそうです。
具体的には、UserService
のソースを書き換えずにUserDao
の実装側で内容をコントロールできます。
というのも、そのインターフェースを実装するクラスがひとつだけの場合、Springがそれをよしなに判別してその実装クラスに紐づけてくれるからです。
一方で、@Qualifier
を付ける場合にはUserService
内に実装側のクラス名が含まれてしまうため、インターフェースを経由していても結局UserService
側の書き換えが必要になりそうです。
インターフェースを経由することで得られるメリットがピンと来ていません。
アノテーションの使い分けもよくわからない
@Component
とか@Repository
とか、SpringでよしなにDIしてもらうためにアノテーションを付けますが、内容に違いはあるのでしょうか。
GitHubでRepositoryのソースを見てみましたが、どうやら@Repository
は@Component
のエイリアスとなっており、実装内容の違いがなさそうです。
もしそうであれば、DIのためのアノテーションは@Component
のみを使ってもよいのでしょうか?
私はまだJavaのソースの追い方がよくわかっていないので間違っているのかもしれませんが、このあたりの動作原理とか使う上での思想的な理由付けがいまいち理解できていません。
もしかしたら
時間がなくて追い切れていないですが、以前に読みかけだったドメイン駆動設計入門に思想面での理由付けなどが書かれていた記憶がおぼろげながらあります。
この本自体はC#をメインに紹介されていますが、どっちもSIerがよく使うオブジェクト指向言語という感じなので、いま読めば必要性がより身近に感じられるのかもしれないと思っています。
よくわからなくても、さらっとなめておくと必要な時にアクセスできるインデックスが自分の中にできるので、いま現在の必要性が薄いと感じる範囲でも積極的な学習は怠らないようにしたいな、と感じました。
いまはお気持ちですが
ちょっとお気持ちだけのオチがない記事ですが、謎が解けたらまた書きます。
もし読者にJavaとかオブジェクト指向に自信ニキの方がいたらTwitterのリプライでもDMでもいいので教えてください。よろしくお願いします。