CDIを使用してJSFプロジェクトを作成しています。 SonarQubeを使用してコードの品質を管理しています。私たちのプロジェクトでスキャンを実行した後にポップアップした問題の1つは、S3306: "Constructor injection should be used instead of field injection"です。SonarQubeに準拠したCDIマネージドBeanで@Injectを使用する方法S3306
それは、例えば、私たちは豆で使用している注入によって引き起こされた:注入
@Named
@ViewScoped
public class AccountsController extends AbstractController<Account> {
@Inject
private AccountsFacade accountsFacade;
public AccountsController() {
super(Account.class);
}
...
}
のようなファサードです:
@Stateless
public class AccountsFacade extends AbstractFacade<Account> {
@PersistenceContext(unitName = "...")
private EntityManager entityManager;
public AccountsFacade() {
super(Account.class);
}
...
}
SonarQubeによって提供されるこの問題に関する情報:
Field injection seems like a tidy way to get your classes what they need to do their jobs, but it's really a
NullPointerException
waiting to happen unless all your class constructors areprivate
. That's because any class instances that are constructed by callers, rather than instantiated by the Spring framework, won't have the ability to perform the field injection.Instead
@Inject
should be moved to the constructor and the fields required as constructor parameters.This rule raises an issue when classes with non-
private
constructors (including the default constructor) use field injection.
推奨解決策:
class MyComponent {
private final MyCollaborator collaborator;
@Inject
public MyComponent(MyCollaborator collaborator) {
Assert.notNull(collaborator, "MyCollaborator must not be null!");
this.collaborator = collaborator;
}
public void myBusinessMethod() {
collaborator.doSomething();
}
}
managed beans are created using a constructor with no arguments以降、SonarQubeルールに準拠する方法はありますか?
編集:私はCDIを使用しています。以前のリンク(Oracleのドキュメント)がここに適用されるかどうかはわかりません。
編集2:私はWELD injection pointsのドキュメントを読んだ後、提案された解決策を試しました。しかし、それは私に、このエラーを与える:
WELD-001435: Normal scoped bean class ...AccountsController is not proxyable because it has no no-args constructor
編集3:編集2の誤差は、他のコントローラ内のAccountsController
の@Inject
によって引き起こされる(質問にコメントを参照)確かです。答えも見てください。
は、あなたはそれが '@Inject 公共MyComponentの(MyCollaboratorコラボ){...}'はなく '公共MyComponentの(@Inject MyCollaboratorする必要がありますよろしいですコラボレーター){...} '?また、http://stackoverflow.com/questions/19381846/why-use-constructor-over-setter-injection-in-cdi – Kukeltje
Hmmmm ....矛盾した情報...(コンストラクタの方法を使用したことはありません)... – Kukeltje
あなたの例は確かに正しいようです...奇妙でbtw ... sonarcube文書の '春のフレームワーク'? Hmmmm sonarcubeルールをオーバーライドする可能性があります;-) – Kukeltje