5

私は Java アプリケーションで Spring を使用しています。これまですべての @Autowired アノテーションが機能していました。

簡単な例は次のとおりです。

  @Component
  public class MyBean implements MyInterface {
      ...
  }

  @Component
  public class MyOtherBean {
      @Autowired
      private MyBean myBean;
      ...
  }

アプリケーションを起動しようとすると、次のようになります。

java.lang.IllegalArgumentException: Can not set MyBean field MyOtherBean.myBean to $ProxyXX

  1. このインターフェイスには、公開されているシンプルなメソッドが 2 つだけ含まれており、クラスはそれらを実装しています。
  2. どちらのクラスもパブリックであり、パブリックのデフォルト コンストラクターがあります。(テストでそれらをインスタンス化しようとさえしました。
  3. セクションを削除するとimplements、すべてが正しく機能します。

インターフェイスの実装で何が問題になる可能性がありますか? とは$ProxyXX?

4

2 に答える 2

11

問題は、MyInterfaceおそらくトランザクション管理またはキャッシングの目的で、Spring が実装する AOP プロキシを注入していることだと思います。MyBeanのメソッドのいずれ@Transactionalかに注釈が付けられているか、または他の注釈で注釈が付けられていますか?

理想的には、インターフェイス タイプで MyBean を参照することをお勧めします。これにより、問題が解決するはずです。

@Component
public class MyOtherBean {
    @Autowired
    private MyInterface myBean;
    ...
}

複数の Bean を実装MyInterfaceしている場合は、常に Bean を名前で修飾します。

@Component
public class MyOtherBean {
    @Autowired
    @Qualifier("myBean")
    private MyInterface myBean;
    ...
}
于 2013-05-24T20:04:02.560 に答える
4

デフォルトでは、Spring は Java 動的プロキシーを使用して、Bean がインターフェースを実装するときに AOP を実装します。問題を解決する最も簡単でクリーンな方法は、インターフェースでプログラムを作成し、具体的なクラスの代わりにインターフェースを注入することです。

@Component
public class MyOtherBean {
    @Autowired
    private MyInterface myBean;
    ...
}

Spring に常に CGLib を使用させる方法については、 http: //static.springsource.org/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#aop-proxying を参照してください。

于 2013-05-24T20:04:45.413 に答える