2015-04-08 99 views
1

由於Spring的AOP實現,有時您想調用同一個類中的方法,您希望該調用通過您的建議。在春天訪問AOP代理的最佳方式是什麼?

這裏有一個簡單的例子

@Service 
public class SomeDaoClass { 
    public int getSomeValue() { 
     // do some cache look up 
     Integer cached = ...; 
     if (cached == null) { 
      cached = txnGetSomeValue(); 
      // store in cache 
     } 

     return cached; 
    } 

    @Transactional 
    public int txnGetSomeValue() { 
     // look up in database 
    } 
} 

現在忽略第二,在春天我可以用@Cached註解緩存,我的例子的一點是,getSomeValue()被通過其他豆類訪問春季代理和運行相關的建議。對txnGetSomeValue的內部調用不會,並且在我的示例中將錯過我們在@Transactional點切換中應用的建議。

訪問代理的最佳方式是什麼,以便您可以應用這些建議?

我最好的辦法很有效,但很笨拙。它大量暴露了實現。我在多年前就知道這一點,並且堅持使用這種尷尬的代碼,但想知道什麼是首選方法。我的hacky方法看起來像這樣。

public interface SomeDaoClass { 
    public int getSomeValue(); 

    // sometimes I'll put these methods in another interface to hide them 
    // but keeping them in the primary interface for simplicity. 
    public int txnGetSomeValue(); 
} 

@Service 
public class SomeDaoClassImpl implements SomeDaoClass, BeanNameAware, ApplicationContextAware { 
    public int getSomeValue() { 
     // do some cache look up 
     Integer cached = ...; 
     if (cached == null) { 
      cached = proxy.txnGetSomeValue(); 
      // store in cache 
     } 

     return cached; 
    } 

    @Transactional 
    public int txnGetSomeValue() { 
     // look up in database 
    } 

    SomeDaoClass proxy = this; 
    String beanName = null; 
    ApplicationContext ctx = null; 

    @Override 
    public void setBeanName(String name) { 
     beanName = name; 
     setProxy(); 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
     ctx = applicationContext; 
     setProxy(); 
    } 

    private void setProxy() { 
     if (beanName == null || ctx == null) 
      return; 

     proxy = (BlockDao) ctx.getBean(beanName); 

     beanName = null; 
     ctx = null; 
    } 
} 

我所做的是添加BeanNameAware和SpringContextAware,這樣我就可以在Spring中查找我的代理對象。醜陋的我知道。任何建議乾淨的方式來做到這一點很好。

回答

1

你可以使用注射@Resource

@Service 
public class SomeDaoClassImpl implements SomeDaoClass { 

    @Resource 
    private SomeDaoClassImpl someDaoClassImpl; 

    public int getSomeValue() { 
     // do some cache look up 
     Integer cached = ...; 
     if (cached == null) { 
      cached = somDaoClassImpl.txnGetSomeValue(); 
      // store in cache 
     } 

     return cached; 
    } 

    @Transactional 
    public int txnGetSomeValue() { 
     // look up in database 
    } 

注意代理:@Autowired將無法​​正常工作。

+0

這正是我期待的那種簡單。不幸的是,當我嘗試它時,我得到了這個bean創建異常消息。創建名爲'someDaoClassImpl'的bean時出錯:注入資源依賴關係失敗;嵌套異常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到符合依賴關係的[SomeDaoClassImpl]類型的合格bean:期望至少1個符合此依賴關係自動裝配候選資格的bean。依賴註釋 –

+0

@Resource按名稱注入,並且只有在未找到時纔回退鍵入。確保您使用的是正確的bean名稱。 –

+0

這樣做!我知道必須有更好的方式,感謝您的幫助。 –

相關問題