1

インターフェースがあります:

public interface NotifyService {

  public void send();

そしてそれを実装するクラス

public class EmailNotifyService implements NotifyService {

  private EmailBuilder _builder;

  @Autowired
  PersonRepository _personRepository;

  ... other Autowired Repositories ...

  public EmailNotifyService(EmailBuilder builder) {
   this._builder = builder;
  }

  public void send() {
    // send mail using _builder.getRecipient().getEmailAddress(), etc.
  }

ビルダーを使用して EmailNotifyService をインスタンス化していました。

public class EmailBuilder {

  private Person _recipient;

  private EmailType _type;

  private Event _event;

  public EmailNotifyService build() {
    return new EmailNotifyService(this);
  }

  public EmailBuilder recipient(Person recipient) {
    this._recipient = recipient;
    return this;
  }

... 等々。しかし今、build() を使用して新しい EmailNotifyService を作成する代わりに、代わりに Spring で Autowire を使用しようとしています。問題は、アプリ内のどこでも、クラスではなく Autowiring インターフェイスであることです。そして、私が読んだことから、それは一般的に良い考えです. 実際、私は NotifyService を Abstract クラスに書き直してから、EmailNotifyService にそれを拡張させてみました。しかし、Spring はそれを正しく Autowiring していません。インターフェイスの場合のように Proxy を作成せず、Autowired フィールドはすべて null です。

そのため、NotifyService インターフェイスの自動配線に行き詰まっているように見えます。罰金。私が理解できないのは、ビルダーで割り当てに使用したデータ (Person、EmailType、および Event) を Spring Autowired インターフェースに取得するにはどうすればよいかということです。

インターフェイス定義を変更して setPerson() や setEmailType() などを持たせることもできると思いますが、それは本当に醜いだけでなく、そもそもインターフェイスを使用する目的を無効にします。別の NotifyService (WebServiceNotifyService または RestNotifyService など) の夜には、その情報は必要ありません。

これを行うためのエレガントでベストプラクティスの方法はありますか?

ありがとう。

編集

私は注釈を使用していますが、xml はほとんどありません。また、トランザクション管理も使用していますが、抽象クラスが適切に自動配線されていない理由を説明できますか? これは私がxmlに持っている唯一の関連情報です:

<context:annotation-config />  
<context:component-scan base-package="com.myco.myapp" />  
<tx:annotation-driven transaction-manager="transactionManager"/>  

「オートワイヤーが正しく機能していない」というのは、抽象クラスをオートワイヤーしようとすると、Spring がインターフェイスのように Proxy を作成していないように見え、EmailNotifyService のすべての Autowired フィールド ( PersonRepository、その他 ...) は null です。インターフェイスを使用すると、すべての Autowired フィールドが正しく配線されます。

しかし、私の主な問題は、ビルダーを使用して新しい EmailNotifyService() を直接作成し、それに情報 (Person、EmailType、および Event) を渡すことで、具体的なクラスを明示的に操作していたことです。これらは普通の豆です。EmailNotifyService にはセッター/ゲッターはありませんが、EmailNotifyService 内に存在していた EmailBuilder があります。

しかし今、Person、EmailType、または Event について何も知らない NotifyService インターフェイスを使用しています。しかし、EmailNotifyService が機能するには、この情報が必要です。

私の質問は、Spring を使用して EmailNotifyService を次のように自動配線する場合です。

@Autowired
@Qualifier("email") // so Spring knows I want to use the EmailNotifyService implementation
NotifyService _notifyService

NotifyService はそれらについて何も知らないので、Person、EmailType、および Event データを設定するにはどうすればよいですか?

現在、Web アプリ内でメーラー サービスを使用していますが、理論的には、メーラー サービスはスタンドアロンで動作できるはずです。いずれにせよ、リクエスト スコープ Bean がここでどのように役立つかはわかりません。

4

1 に答える 1