3

Web サービスへの有効な呼び出しがあります。アノテーションで構成された Spring Bean を使用して Web サービスを呼び出すロジックを実装します。

@ManagedResource(objectName = "bean:name=XServiceMBean")
@Service("xService")
public class XServiceImpl implements XService
{
// working code here
}

テスト目的で、このクラスを拡張し、このクラスの代わりにサブクラスを注入したいので、次のように作成しました。

@ManagedResource(objectName = "bean:name=XServiceMBean")
@Service("xService")
public class XServiceImplTest extends XServiceImpl
{
// working code here
}

スーパークラスの 2 つの注釈行をコメントアウトしました。

春はそれが好きではありません。実行すると、次のようになります。

Error creating bean with name 'xService':Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'xService' must be of type [com.hsc.correspondence.rules.XService], but was actually of type [com.hsc.correspondence.rules.impl.XServiceImplTest]

明示的な「サブクラスに XService を実装する」をもう一度試してみましたが、同じ結果が得られました。

私は春に何か違法なことをしていますか? 元の XServiceImpl には、多数の @Resource アノテーションが含まれています。それが問題になるとは思いませんでした。以前と同じように注射されることを期待していました。

私がやりたいことを行う方法はありますか?それは、オリジナルへの絶対的な変更を最小限に抑えたテストクラスを持っていますか? (私が取り組んでいるプロジェクトでそれらの決定を下さないことを除いて、XML で構成することを検討しますが、私がやろうとしていることには問題があるとは思いませんでした.


追加の困惑: エラー メッセージには、「'xService' という名前の Bean は ...XService 型である必要がありますが、実際には XServiceImplTest 型でした」と表示されます。しかし、XServiceImplTest は XServiceImpl と同じように XService を実装します。

追加の難問 #2: XServiceImpl 全体をクラス XServiceImplTest にコピーし、XServiceImpl の注釈をコメント アウトし、クリーンアップして再構築し、実行しました。同じ結果が得られました。2 つのクラスの唯一の違いは、クラス名です。それはますます見知らぬ人になります。Springがクラス名を気にする理由を誰かが提案できますか?

4

2 に答える 2

1

これには 3 つの原因が考えられます。

  1. コードは表示されているものとは異なり、継承階層はありません。(インターフェイスを直接追加したと言うので、これはありそうにありませんが、インポートを再確認することをお勧めします)

  2. クラスパスに古いコンパイル済みクラスがあります。XServiceImplTest の周りに古いコンパイル済みバージョンがある場合、これが検出される可能性があります。すべてのクラス/ターゲット フォルダーを消去してみてください。

  3. ある種のクラスローダーの問題で実行しており、テスト実装とは異なるクラスローダーによってインターフェイスが読み込まれます。execption がスローされる行にブレークポイントを置き、関連するさまざまなクラスのクラスローダーを調べます。

    x.getClass().getClassLoader()関心のある任意のインスタンスに対して行うことで、それを行うことができます。プレーンなバニラ アプリケーションでは、これはすべての x に対して同じインスタンスを返します。OSGI アプリケーションと Web アプリケーションでは、異なる ClassLoader を取得する場合があります。ClassLoader のタイプとその親関係シップは、何が起こっているかについてのヒントを与えるはずです。

于 2013-04-08T18:47:04.573 に答える
0

同じ名前を持つことはできません。両方のクラスに「xService」を呼び出しています。たとえば、サブクラスに別の名前「xServiceTest」を付けて、@Qualifier を使用してそれを注入できます。その他、100% 確実ではありませんが、この種の継承で問題が発生する可能性があると思います。ある場合は、共通の実装をすべて持つ抽象クラスを作成してから、サービスとテストの 2 つのサブクラスを作成します。

お役に立てれば。

[アップデート]

Springがクラス名を気にする理由を誰かが提案できますか?

context:component-scan奇妙なエントリの構成をチェックインできます。次のように定義されているかどうかを確認します。

 <context:component-scan resource-pattern="<path>/*Impl.class" ...> 

および/またはいくつかの特定の包含/除外基準。

于 2013-04-08T18:46:17.020 に答える