2017-02-14 22 views
0

我有一個名爲PersonDAOImpl的類,我使用Hibernate在我的數據庫上保存數據。如何編寫一個切入點以獲得對類方法的操作?

爲了審計該類,我使用@Aspect註釋創建了另一個類,其中我聲明瞭一些Pointcuts和Advices。每當我插入,更新或刪除一個人時,我都可以在表格上存儲有關所執行操作的適當信息。

但是現在我有更多的DAO類,我不想爲每個DAO上的每個方法創建更多方面類或更多的Advices。相反,我想要在單個切入點中「捕獲」persist(),update()或delete()的操作。

比如我有我的DAO這種方法:

@Override 
@Transactional 
public void addPerson(Person p) { 
    Session session = this.sessionFactory.getCurrentSession(); 
    session.persist(p); 
    session.flush(); 
    logger.info("Person saved successfully, Person Details="+p); 
} 

而且我這是怎麼審覈的插入:

@Pointcut("execution(* com.dacasals.raspertwo.dao.PersonDAOImpl.addPerson(..))") 
public void addNewPerson() { 
} 

@After("addNewPerson()") 
public void aP() { 
    System.out.println("added a new person"); 
    operation = "Insert"; 
    date = Calendar.getInstance().getTime(); 
    register(operation, date); 
} 

但我想是@Pointcut(「執行(* COM .dacasals.raspertwo.dao.anydaoclass.anymethod.persist(..))「)

我的意思是在調用persist()的任何DAO類上的任何方法的切入點。 update()和delete()同樣的事情。

我該如何做到這一點?我嘗試過'內'和'內碼',但沒有任何反應。提前致謝。

+0

不要使用AOP爲,但使用該JPA實體監聽器,這些都是專爲。 –

回答

0

而不是執行表達式,你可能想使用內部表達式就像這樣。

within(com.yourpackage..*) 

爲此,您必須確保您的所有DAO都在此包裝內。上述表達式將匹配package com.yourpackage和classes子包內的類中定義的所有方法。

下面是一個簡短的文檔,如果你想對它進行配置一些其他的方式, Pointcut Expressions in Spring

+0

我已將所有DAO類放在同一個包中,現在,如何使用示例訪問方法addPerson中的persist()? – Ethan

+0

該表達式應攔截方法調用。 –

0

我會使用「AroundAdvice」。

報價爲文檔:

Around advice runs "around" a matched method execution. It has the opportunity to do work both before and after the method executes, and to determine when, how, and even if, the method actually gets to execute at all.

Around Advice Spring documentation

所以,在你的榜樣,你將有一個方法:

@Around("com.dacasals.raspertwo.dao.*.persist(..)") 
public Object doSomething(ProceedingJoinPoint pjp) throws Throwable { 

} 

這樣對「com.dacasals每次有人.raspertwo.dao'調用持續方法,Spring Aspect將調用doSomething方法。在方法執行前後,周圍的建議都可以工作,所以你應該注意不要兩次做同樣的事情。

我會爲每個操作創建一個特定的方法(一個用於插入,另一個用於更新和刪除),但是您可以使用使用短路操作的相同方法。這樣一來,你的@Around註釋是這樣的:

@Around("com.dacasals.raspertwo.dao.*.persist(..) || com.dacasals.raspertwo.dao.*.update(..) || com.dacasals.raspertwo.dao.*.delete(..)") 
public Object doSomething(ProceedingJoinPoint pjp) throws Throwable { 

} 
+0

當我添加你的例子,我得到一個錯誤:切入點是畸形的:錯誤通配符類型模式不允許,必須使用類型名稱 – Ethan

+0

我也試過這個: \t @Pointcut(「execution(* com.dacasals.raspertwo.dao。 * .persist(..)) 「) \t公共無效方法(){} \t \t @Around(」 方法()「) \t公共無效DoSomething的(ProceedingJoinPoint PJP)拋出的Throwable { \t \t pjp.proceed (); \t \t System.out.println(「It works!」); \t \t operation =「Insertado」; \t \t date = Calendar.getInstance()。getTime(); \t \t register(operation,date); \t} 它沒有工作。我將表達式更改爲@Pointcut(「execution(* com.dacasals.raspertwo.dao.PersonDAOImpl.addPerson(..))」),它工作正常!任何想法? – Ethan

+1

布魯諾,如果'@ After'便宜了,爲什麼要用'@ Around'?更昂貴的建議類型不能解決問題,正確的切入點確實如此。 Ethan,難怪這個方法的名字是'persist'和'update'(只是例子!)與名爲'addPerson'的方法不匹配。如果你在複製和粘貼代碼之前想一點點,你可以自己回答。順便說一句,爲了使代碼更加穩定並且也影響到子包,我建議你使用'''這樣的符號:'execution(* com.dacasals.raspertwo.dao .. *(..))'或者只是'在(com.dacasals.raspertwo.dao .. *)' – kriegaex

相關問題