初めて Spring を触って、@Autowired の便利さに感動したので・・・
(フィールドだけでなくセッターメソッドに対しても使用可能)
つまり、コンストラクタやフィールドの右辺に、フィールドの初期化処理を書かなくてよくなる。
古い Spring では初期化設定を xml に書く必要があったが、今はアノテーション(C# での カスタム属性)のみで完結できるようになっている。
[@Autowired サンプル]
DI 目的なら HogeService と HogeDao のインターフェースを用意した方がいいけど、ここでは省略。
@Autowired 可能なクラスは、@Component 派生アノテーション付きで、@ComponentScan 対象である必要がある。(もしくは xml に記述したクラス)
つまり、フィールドとしてしか作れない。(@Controller もフレームワークのフィールドみたいなもの)
@Autowired 持ちクラスをフィールドじゃなく、ローカル変数として欲しい(コードで手動生成したい)ケースが稀にあると思う。
java - In Spring, can I autowire new beans from inside an autowired bean? - Stack Overflow の createAutowiredObject で簡単に生成できる。
@Component 付クラスである必要もない。
[createAutowiredObject 使用サンプル]
@Scope("prototype") を付けることで非シングルトンにすることも可能だが、親クラスも同じ @Scope を設定してやる必要がある。(シングルトンのフィールドは同じくシングルトンになる)
親クラスがシングルトンで、その内部で非シングルトンの @Autowired 持ちクラスが欲しい場合、createAutowiredObject のようなメソッドがあるといいかもしれない。
親クラスの @Scope を変えても可能だが、変えられないケースもあると思うので。
前置き
@Autowired について簡単に説明すると、自動で初期化されるフィールドの目印。(フィールドだけでなくセッターメソッドに対しても使用可能)
つまり、コンストラクタやフィールドの右辺に、フィールドの初期化処理を書かなくてよくなる。
古い Spring では初期化設定を xml に書く必要があったが、今はアノテーション(C# での カスタム属性)のみで完結できるようになっている。
[@Autowired サンプル]
@Controller
public class HogeController {
@Autowired
private HogeService service;
// 以降、URL 割り当てメソッド
}
@Service
public class HogeService {
@Autowired
private HogeDao dao;
// 以降、サービスメソッド
}
@Component
public HogeDao {}
HogeController にマップされた URL アクセス時、HogeController インスタンスがフレームワークによって生成され、@Autowired フィールドの service にも HogeService インスタンスが割り当てられる。HogeService の dao フィールドも @Autowired なので同様。DI 目的なら HogeService と HogeDao のインターフェースを用意した方がいいけど、ここでは省略。
@Autowired 可能なクラスは、@Component 派生アノテーション付きで、@ComponentScan 対象である必要がある。(もしくは xml に記述したクラス)
@Autowired 持ちクラスを手動で生成
上記サンプルのような使い方だと、@Autowired 持ちクラスが初期化されるためには、@Autowired フィールドとして生成されるか、@Controller のようにフレームワークから自動生成される必要がある。つまり、フィールドとしてしか作れない。(@Controller もフレームワークのフィールドみたいなもの)
@Autowired 持ちクラスをフィールドじゃなく、ローカル変数として欲しい(コードで手動生成したい)ケースが稀にあると思う。
java - In Spring, can I autowire new beans from inside an autowired bean? - Stack Overflow の createAutowiredObject で簡単に生成できる。
@Component 付クラスである必要もない。
[createAutowiredObject 使用サンプル]
@Controller
public class HogeController {
@Autowired
private AutowireCapableBeanFactory factory;
private <T> T createAutowiredObject(Class<T> c){
return factory.createBean(c);
}
public void createAutowiredTest(){
HogeComponent component = createAutowiredObject(HogeComponent.class);
// HogeComponent のフィールドが初期化されていることを確認
System.out.println(component.sub);
}
}
public HogeComponent {
@Autowired
public HogeComponentSub sub;
}
@Component
public HogeComponentSub {}
使いどころ
@Component 付きクラスは、デフォルトでシングルトンである。@Scope("prototype") を付けることで非シングルトンにすることも可能だが、親クラスも同じ @Scope を設定してやる必要がある。(シングルトンのフィールドは同じくシングルトンになる)
親クラスがシングルトンで、その内部で非シングルトンの @Autowired 持ちクラスが欲しい場合、createAutowiredObject のようなメソッドがあるといいかもしれない。
親クラスの @Scope を変えても可能だが、変えられないケースもあると思うので。