2011-01-16 47 views
2

創建我有一個POJO類與@Transactional春天開始一個事務由新

public class Pojo { 

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

Spring聲明式事務管理註釋的方法目的是基於AOP的,但我沒有與任何經驗。我的問題是: 是否有可能在單獨調用(new Pojo).doInTransaction()時,Spring將啓動一個事務。

回答

3

Spring聲明式事務管理 基於APO但我不 有那方面的經驗。

我建議開始使用它,您將獲得使用AOP使用交易通知的體驗。一個好的起點是here

是否有可能調用 (新POJO)時.doInTransaction單獨(), 春天將開始交易。

不,你不能指望Spring知道你手動調用的bean。但是,這聽起來像是你想要避免聲明式事務管理和編程式事務管理。有一種方法可以通過使用Transaction Template來實現。那是你在找什麼?

0

Spring通過Annotation處理事務的方式正如您所說的那樣使用AOP。 的AOP位使用動態代理實現(見doc

所以爲了做到這一點,你會通過Spring容器需要檢索您的類的實例(POJO這裏),因爲,使其工作,將春通過Pojo返回一個動態代理服務器,該服務器將自動包含任何帶有交易管理代碼的帶註釋的方法。

如果你只是做一個

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

春天沒有任何這方面發揮作用,你的方法調用不會在事務內。

,所以你需要做的就是這樣的事情

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

注:這是一個例子,你應該更喜歡的,而不是從上下文

手動檢索你的bean這樣依賴注入,並且使用正確配置的Spring Context,Spring應該瞭解您的類以掃描事務性註釋並自動將您的bean包裝爲註釋感知的動態代理實例。從你的觀點來看,這並沒有改變任何東西,你仍然會將你的對象投射到你自己的類,但是如果你試圖打印出你的春天上下文Pojo bean的類名,你會得到一些代理$。 ..而不是你原來的班級名稱。

看一看這個鏈接反正:link text

1

這是有點可能,但以一種麻煩的方式:您必須使用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 

    } 

} 

這不是最好的做法。首先,它使您的應用程序高度意識到Spring Framework,並且違反了依賴注入原則。所以只有在沒有其他方式的情況下才能使用它!