7

次のような一般的なDaoインターフェイスで@Autowiredアノテーションを使用しようとしています。

public interface DaoContainer<E extends DomainObject> {
    public int numberOfItems();
    // Other methods omitted for brevity 
}

私はコントローラーでこのインターフェースを次のように使用しています。

@Configurable
public class HelloWorld {
    @Autowired
    private DaoContainer<Notification> notificationContainer;

    @Autowired
    private DaoContainer<User> userContainer;

    // Implementation omitted for brevity
}

次の構成でアプリケーションコンテキストを構成しました

<context:spring-configured />
<context:component-scan base-package="com.organization.sample">
<context:exclude-filter expression="org.springframework.stereotype.Controller"
   type="annotation" />
</context:component-scan>
<tx:annotation-driven />

Springは私のDaoContainerの1つのインスタンス、つまりDaoContainerのみを作成して注入するため、これは部分的にしか機能しません。言い換えれば、userContainer.numberOfItems();に尋ねると 私はnotificationContainer.numberOfItems()の数を取得します

強く型付けされたインターフェースを使用して、次のような正しい実装をマークしようとしました。

public interface NotificationContainer extends DaoContainer<Notification> { }
public interface UserContainer extends DaoContainer<User> { }

そして、次のようにこれらのインターフェイスを使用しました。

@Configurable
public class HelloWorld {
    @Autowired
    private NotificationContainer notificationContainer;
    @Autowired
    private UserContainer userContainer;
    // Implementation omitted...
}

悲しいことに、これはBeanCreationExceptionに失敗します。

org.springframework.beans.factory.BeanCreationException: Could not autowire field:   private com.organization.sample.dao.NotificationContainer com.organization.sample.HelloWorld.notificationContainer; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.organization.sample.NotificationContainer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

今、私はどのように進めるべきか、あるいは複数のDaoを使用することさえ可能であるかについて少し混乱しています。どんな助けでも大歓迎です:)

4

2 に答える 2

2

わかりました、このパズルのかなり合理的な解決策を見つけたと思います。これに対処する 1 つの方法は、ドメイン モデル内のすべてのエンティティのインターフェイスと実装を作成することです (Espen が以前の回答で指摘したように)。ここで、数百のエンティティとそれぞれ数百の実装があることを検討してください。それは正しくないと思いませんか?

厳密に型指定されたサブインターフェイスを破棄し、代わりにジェネリック インターフェイスを使用しています。

@Service // Using @Service annotation instead @Configurable as Espen pointed out
public class HelloWorld {
    @Autowired
    private DaoContainer<Notification> notificationContainer;

    @Autowired
    private DaoContainer<User> userContainer;

    // Implementation omitted
}

私の DaoContainer インターフェイスの実装は次のようになります。

@Repository
public class DaoContainerImpl<E extends DomainObject> implements DaoContainer<E> {

    // This is something I need in my application logic
    protected Class<E> type;

    public int getNumberOfItems() {
       // implementation omitted
    }
    // getters and setters for fields omitted

}

最後に、アプリケーション コンテキスト:

<context:spring-configured />
<context:component-scan base-package="com.organization.sample">
<context:exclude-filter expression="org.springframework.stereotype.Controller"
    type="annotation" />
</context:component-scan>

<bean class="com.organization.sample.dao.DaoContainerImpl" id="userContainer">
    <property name="type" value="com.organization.sample.domain.DiaryUser" />
</bean>
<bean class="com.organization.sample.dao.DaoContainerImpl" id="notificationContainer">
    <property name="type" value="com.organization.sample.domain.DiaryNotification" />
</bean>

したがって、基本的に純粋な汎用自動配線を機能させることはできませんでしたが、この解決策は私にとってはうまくいきます(少なくとも今のところ):)

于 2010-05-19T05:50:02.080 に答える
0

好きなだけ Bean を自動配線することができます。

ただし、タイプごとの自動配線を使用している場合は、各インターフェイスの Bean の 1 つだけにすることができます。エラー メッセージは、指定されたインターフェイスの Spring コンテナーで使用できる Bean がないことを示しています。

解決策:

不足している DAO 実装:

@Repository
public class NotificationContainerImpl implements NotificationContainer {}

@Repository
public class UserContainerImpl implements UserContainer {}

あなたのサービスクラス:

@Service
public class HelloWorld {
    @Autowired
    private NotificationContainer notificationContainer;
    @Autowired
    private UserContainer userContainer;
    // Implementation omitted...
}

@Configurable注釈をに置き換えました@Service@Configurableは AspectJ と一緒に使用され、ここで必要なものではありません。@Componentまたはのような特殊化を使用する必要があります@Service

com.organization.sampleまた、Spring コンテナーがそれらを見つけられるように、パッケージ内にすべての Spring コンポーネントを含めることを忘れないでください。

これが役立つことを願っています!

于 2010-05-17T09:59:32.000 に答える