0

Web サービス、サービス層、ドメイン層の 3 層アプリケーションがあります。Web サービスは、Web アプリケーション (WAR) に存在します。サービス層とドメイン層は 2 つの JAR プロジェクトです。依存関係は次のとおりです。

web-service --> サービス層 --> ドメイン層

サービス層では、サービスに の注釈が付けられ@Serviceます。ドメイン層では、DAO に の注釈が付けられ@Repositoryます。Web サービス実装クラスはサービス層 JAR のサービスを使用するため、自動的に注入される各サービスの 1 つのインスタンスを保持します ( @Autowired)。

依存関係は私のPOMで明確に定義されています。WAR を Tomcat にデプロイすると、次の例外が発生します。

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycompany.project.services.MyService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:952)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:551)
    ... 37 more

Spring docs の関連する部分から引用します。

クラスパス パッケージをスキャンするには、クラスパスに対応するディレクトリ エントリが存在する必要があります。Ant で JAR をビルドするときは、JAR タスクのファイルのみのスイッチを有効にしないようにしてください。

確認したところ、サービス層の JAR は WEB-INF/lib ディレクトリにあります。

何か案が?

ありがとう


編集:の下の Web サービス層プロジェクト (WAR) にあるコンテキスト ファイルは 1 つだけですsrc/main/webapp/WEB-INF。このコンテキストでは、次のようにクラスパス スキャンを有効にしました。

<context:component-scan base-package="com.mycompany.project" />

パッケージcom.mycompany.projectは私のプロジェクトの基本パッケージで、その下に web-service ( com.mycompany.project.server)、service-layer ( com.mycompany.project.services)、および domain-layer ( com.mycompany.project.domain) パッケージがあります。

私は問題を解決しました。なぜ私がしたことがそのような問題を引き起こしたのか理解できません。各サービスは、そのパブリック メソッドを定義するインターフェイスを実装します。私の Web サービス実装クラスでは、サービスへの参照はインターフェイスではなく実装クラスを使用していました。インターフェイスを使用するように変更したところ、問題は発生しなくなりました。自動配線のインターフェースの代わりにサービス実装クラスを使用することの何が問題なのか、誰か説明してもらえますか?

4

3 に答える 3

2

これはあなたの編集に対する答えです:

インターフェースの参照は機能したが、具体的な実装が失敗した理由は、おそらく、Spring がサービスにアノテーションを付けた場合などに作成する動的プロキシ@Transactionalに関係しているためです。そのような場合に何が起こるかは、Bean のタイプが実装タイプはもうありませんが、実装タイプをラップします。したがって、実装タイプごとに @Autowired がある場合、タイプごとに見つけることができません (これがデフォルトです)。

動的プロキシは、実装用に定義したインターフェイスから引き続き派生し、インターフェイスの種類によって注入できるため、修正は非常に適切です。私が提供した参照は、これを説明するより良い仕事をします。

于 2012-08-28T20:18:06.487 に答える
0
  1. 使用したことを確認してください<context:component-scan base-package="your.service.package"/>
  2. 自動配線された戦略がbyNameorであることを確認してくださいbyType。の場合byNameService注釈の名前の値は正しいはずです。
  3. 問題が解決しない場合は、Spring のログを確認してください。見つかったすべてのコンポーネントの名前が出力され、サービスが確立されているかどうかがわかります。
于 2012-08-28T15:39:03.203 に答える
0

コンポーネント スキャンの構成を表示できますか? これが正しく設定されていない場合、Spring がサービスを検出していない可能性があります。

次のようなものが必要です。

<context:component-scan base-package="your.service.package"/>

編集:

@Service問題は、注釈が実装クラスではなくインターフェイスにあることだと思います。

サービスの実装に注釈を付ける場合、Web コントローラーは次のいずれかを使用できます。

@Autowired
private ExampleService service;

また

@Autowired
private ExampleServiceImpl service;
于 2012-08-28T15:32:01.273 に答える