3

アノテーションが付けられたメソッドを持つPOJOクラスがあります@Transactional

public class Pojo {

    @Transactional
    public void doInTransaction() {
        ...
    }
}

Spring の宣言型トランザクション管理は AOP に基づいていますが、私はその経験がありません。私の質問は次のとおりです(new Pojo).doInTransaction()。単独で呼び出したときに、Spring がトランザクションを開始する可能性はありますか。

4

4 に答える 4

3

Spring の宣言型トランザクション管理は APO に基づいていますが、私はその経験がありません。

AOP を使用してトランザクション アドバイスを使用する経験を積むことができます。良い出発点はここにあります。

(new Pojo).doInTransaction() だけを呼び出すと、Spring がトランザクションを開始する可能性はありますか。

いいえ、Spring が手動で呼び出した Bean を認識することは期待できません。ただし、宣言的なトランザクション管理を避け、プログラムによるトランザクション管理を行いたいようです。Transaction Templateを使用して Spring でそれを行う方法があります。それはあなたが探していたものですか?

于 2011-01-16T18:57:10.493 に答える
2

AutowireCapableBeanFactoryある程度は可能ですが、面倒な方法で:メカニズムを使用する必要があります。

例としてトランザクションクラスを次に示します

public interface FooBar{
    void fooIze(Object foo);
}

public class FooBarImpl implements FooBar{
    @Transactional
    @Override
    public void fooIze(final Object foo){
        // do stuff here
    }
}

そして、これを使用する方法は次のとおりです。

public class FooService implements ApplicationContextAware{

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(
    final ApplicationContext applicationContext){
        this.applicationContext = applicationContext;
    }

    public void serviceMethod(){

        //declare variable as interface, initialize to implementation
        FooBar fooBar = new FooBarImpl();

        // try to use it, won't work, as it's not a proxy yet
        Object target = new Object[0];
        fooBar.fooIze(target); // no transaction

        // now let spring create the proxy and re-assign the variable
        // to the proxy:
        fooBar = // this is no longer an instance of FooBarImpl!!!
            (FooBar) applicationContext
                .getAutowireCapableBeanFactory()
                .applyBeanPostProcessorsAfterInitialization(fooBar,
                    "someBeanName");
        fooBar.fooIze(fooBar); // this time it should work

    }

}

これはベスト プラクティスではありません。1 つには、アプリケーションが Spring Framework を高度に認識するようになり、また、依存性注入の原則に違反します。他に方法がない場合にのみ使用してください。

于 2011-01-17T08:34:00.047 に答える
1

はい、可能ですSpring は、機能するために動的プロキシを使用する必要はありませ@Transactional。代わりに、AspectJ が提供する「真の AOP」を使用できます。

詳細はhttp://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-aspectjを参照

于 2011-06-10T12:41:48.353 に答える
0

あなたが言ったように、Springがアノテーションを介してトランザクションを処理する方法はAOPを使用しています。AOP ビットは動的プロキシを使用して実装されます (ドキュメントを参照) 。

そのためには、Spring コンテナーを介してクラスのインスタンス (ここでは Pojo) を取得する必要があります。これを機能させるために、Spring は Pojo を介して動的プロキシを返し、注釈付きのメソッドを自動的にトランザクション管理コード。

単純に

Pojo p = new Pojo();
p.doInTransaction();

ここでSpringが果たす役割はなく、メソッド呼び出しはトランザクション内にはありません。

だからあなたがする必要があるのはこのようなものです

ApplicationContext springContext = ...;
Pojo p = (Pojo) springContext.getBean("your.pojo.id");
p.doInTransaction();

注: これは一例です。Bean をコンテキストから手動で取得するのではなく、依存性注入を優先する必要があります。

そうすることで、適切に構成された Spring コンテキストを使用して、Spring はクラスを監視してトランザクション アノテーションをスキャンし、Bean をアノテーション対応の動的プロキシ インスタンスに自動的にラップする必要があります。何も変更しない観点からは、オブジェクトを独自のクラスにキャストしますが、Spring コンテキスト Pojo Bean のクラス名を出力しようとすると、Proxy$ として何かが得られます。 ..元のクラス名ではありません。

とにかくこのリンクを見てください:リンクテキスト

于 2011-01-16T18:41:06.957 に答える