4

<bean>私の Spring アプリケーションには、XML 構成で単純な s として作成された大量の Bean (この場合は DAO) があります。これらのメソッドには、特に を含むさまざまな注釈があり@Transactionalます。私も当然そう<tx:annotation-driven />です。

しかし、これらのオブジェクトの一部 (一部のみではありますが) では、プロキシが作成されず (デバッグ ログを有効にすることでこれを確認しました)、@Transactional注釈は効果がありません。代わりに、これらの DAO への (通常は自動配線された) 参照を含むオブジェクトは、プロキシではなく、直接のクラスへの参照に配線されます。

すべてのクラスには対応するインターフェースがあり、自動配線された参照は常にこれらのインターフェースを介して行われます。

どのクラスがプロキシを取得し、どのクラスが取得しないのかわかりません。私はそれらすべてをしたい。だから私の質問は:

a) いくつかのインターフェースを実装しているにもかかわらず、Spring がクラスのプロキシを作成しないのはどのような状況ですか?

b) Spring に必要なプロキシを強制的に作成させるにはどうすればよいですか?

プロキシを明示的に有効にするために何もしていないことに注意してください。ただし、過去にはその必要はありませんでした。通常は機能します。

Spring 3.1.3 と 3.2.2 の両方で試しました。

私はこれのための SSCCE を持っていません。基本的に私のXMLは

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"       
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:sec="http://www.springframework.org/schema/security"    
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"                       
       xmlns:cache="http://www.springframework.org/schema/cache"       
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
       http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
       http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.2.xsd
       http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
">

       <bean id="userDao" class="com.soschat.dao.spring.SpringUserDAO"/>

           <tx:annotation-driven transaction-manager="transactionManager" />

    <bean id="transactionManager" class=" org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
        <property name="globalRollbackOnParticipationFailure" value="false" />
    </bean>

... etc ...
</beans>

私のコードは多かれ少なかれ

public class UserDaoImpl implements UserDao {

   @Override
   @Transactional
   @Cacheable
   public User getUserById(long userId) {
         // do stuff
   }
}

過度の詳細がなければ、どれだけ追加する必要があるかわかりません。

興味深い追加の 1 つ - BeanNameAutoProxyCreator を使用して強制的にプロキシを作成することができます。しかし、そこに追加した注釈は実際には有効になりません。

4

3 に答える 3

4

@Componentアノテーションは、Spring にそのクラスの Bean を作成して処理するように指示します。アプリケーション (または他の) コンテキストで、要素を使用してそのクラスのパッケージをスキャンする必要があります<component-scan>

@Service@Repository、 と@Controller同じように機能し@Componentます。

プロキシに関しては、Spring はすべてをプロキシするわけではなく、動作を追加する必要があるクラスのインスタンスのみをプロキシします。たとえば、 では@Transactional、begin/commit/rollback トランザクション動作を追加する必要があります。これを行うには、クラスのメソッドを独自のコードでラップするため、プロキシする必要があります。@Controllerクラスの場合、動作を追加する必要がないため、クラスをインスタンス化するだけです。

于 2013-05-10T20:01:17.553 に答える
2

最終的に、何らかの形で「早すぎる」ロードされた Bean で始まるある種の依存関係チェーンのために失敗していることがわかった - 私の場合は、Spring Security PermissionEvaluator。私はまだ SSCCE を持っていませんが、他の誰かが同様の問題を抱えている場合に備えて、ここにこの回答を追加しています。

解決策は、非常に遅いバインディングを使用することでした。私は を作成PermssionEvaluatorApplicationContextAware、 からローカルの bened 参照をロードするプライベート メソッドを作成しましたApplicationContext。このメソッドは、初期化中ではなく、最初に必要になったときにのみ呼び出されます。

言い換えれば、私は次のような豆を持っていました

private AuthorizationServices authServices;

そして、私のメインメソッドでは次のようなものです

if (authServices == null)
   initBeans();

その後

private void initBeans() {
    authServices = ac.getBean(AuthorizationServices.class);
}
于 2013-06-13T18:54:11.867 に答える