1年前。仕事しながら、
そもそも「DIとnewってなにがちがうんだっけ」とおもったので調べた。
てかSpring DIってなにやってくれてるの?
DIってnew省略してくれてるんでしょ?くらいにしかおもって
なかった(反省。)けど、もっと多くのことをやってくれていると知る。
@Component と @Autowired のやっていること
- @Component使う=bean定義を省略する ということ。
- @Autowired使う=コンテナからbeanを引っ張りだして注入する ということ。
Springは起動時にbeanを読み込んでIoCコンテナに登録してるわけだから、
コンポーネントとして定義した部分はSpringコンテナの管理下におかれる。
、、で、依存性注入の際にコンテナ上から呼び出される。
つまり、 DIはコンテナ経由じゃないとだめなのですね。
単純なnewとDIがちがうということはこれで理解できる。
Spring DIはデフォルト、シングルトン
デフォルトだと一つのインスタンスを、依存性注入された各インスタンスが
共有して参照しあってている状態。
これが何を意味するか。
スレッドセーフじゃないことが起こりうるということらろう。
これは逆にいえば、@Componentを付与すべきクラスはステートレスであるべしということ。
具体的には、フィールド変数持っちゃうと意図しない動作になりうる。
どうしてもステートフルなものをコンポーネントで管理したいときは
@Scopeを使うみたいだ。一例、@Scope("prototype")だと、
Beanが呼び出されるたびにインスタンスが作られるので値を共有することはなくなる。
基本的にはデフォルト(シングルトン)にしないほうが安全みたいですね。