私が知っているように、field injection
は推奨されません。代わりにconstructor
を使用してください。
ここで私がやろうとしているのは、基本クラスのコンストラクターで@Autowired
を使用し、すべてのサブクラスがアクセスできるようにすることです。一部のサブクラスでは、コンストラクターから@Autowired
になる特定のBeanも必要です。デモコードは次のとおりです:
基本クラス:
public abstract class Base {
protected final MyDemoService myDemoService;
@Autowired
public Base(MyDemoService myDemoService) {
this.myDemoService = myDemoService;
}
}
継承された(サブ)クラス:
public class Sub extends Base {
private final MySubService mySubService;
@Autowired
public Sub(MySubService mySubService) {
this.mySubService = mySubService;
}
}
これにより、「デフォルトコンストラクターなし」エラーが発生します。
これは質問に似ています: 類似した質問と回答 ですが、ここでは機能しません。
私はしばらくこれに飛び込んできました、dependency injection
に関するこの記事を見つけました: さらに読む
私の質問にはSetter Injection
が正しい方法だと思いますか?
セッター注入:
public abstract class Base {
protected MyDemoService myDemoService;
@Autowired
public void setMyDemoService(MyDemoService myDemoService) {
this.myDemoService = myDemoService;
}
}
私はJava Spring Bootを初めて使用するので、皆さんから専門知識のアドバイスを受けたいと思っています。どんな議論も大歓迎です!
あなたが提供するコードはコンパイルされません。基本クラスにデフォルトのコンストラクタがない限り、子でsuper(MyDemoService)
を呼び出す必要があります。
継承された(サブ)クラス:
public class Sub extends Base {
private final MySubService mySubService;
@Autowired
public Sub(MySubService mySubService, MyDemoService myDemoService){
super(myDemoService);
this.mySubService = mySubService;
}
}
または、MySubService
がMyDemoService
の実装である場合
@Autowired
public Sub(MySubService mySubService){
super(mySubService);
}
抽象クラスのフィールドMyDemoService myDemoService
がprotected
である限り、サブクラスで使用できます。
MyDemoService
を複数実装している場合は、 説明した回答 の説明に従って@Qualifier
を使用する必要があります。
public Sub(@Qualifier("MySubService") MyDemoService mySubService){
super(mySubService);
}
フィールドインジェクションは使用せず、必要に応じてスーパーコンストラクターにコールバックするコンストラクターインジェクションを使用してください。
コンストラクター注入は、インスタンス化の前にオブジェクトが適切に入力されることを保証しますが、セッター注入はそうではなく、コードをよりバグが発生しやすくします(別のnullポインターのバグではありません...)。
記述する必要がある追加のコードが心配な場合は、Project Lombokを使用して、Lombokにコンストラクターコードを生成させます フィールドインジェクションが悪である理由 )
ちなみに、Spring 4の時点では、クラスにコンストラクターが1つしかない場合、コンストラクターに@Autowiredは必要ありません。
@Configuration
クラスの使用をお勧めします。これにより、Springアノテーションをビジネスクラスから完全に削除できます。
public class Sub extends Base {
private final MySubService mySubService;
public Sub(MySubService mySubService, MyDemoService myDemoService){
super(myDemoService);
this.mySubService = mySubService;
}
}
春の構成:
@Configuration
public class SubConfig{
@Bean
public Sub sub(MySubService subService, MyDemoService demoService){
return new Sub(subService, demoService);
}
}
構成クラスを使用すると、魔法のクラスパススキャンに依存することはなくなりますが、実際にはBeanを手動で再度インスタンス化します。このアプローチでは、それほど驚きはありません。
できます!!!!コンストラクターAutowired修飾子の継承注入
基本抽象クラスDocumentoBase。
@Qualifier("DocumentServiceBase")
private DocumentService documentService;
@Autowired
public DocumentoBase(@Qualifier("DocumentServiceBase") DocumentService documentService){
this.documentService = documentService;
}
継承クラスDocumentoController。
@Qualifier("DocumentServiceImplv13")
private DocumentService documentService;
@Autowired
public DocumentoController(@Qualifier("DocumentServiceImplv13") DocumentService documentService){
super(documentService);
this.documentService = documentService;
}