2014-10-30 101 views
0

我必須對屬於com.mycomp的包和子包的所有方法應用日誌記錄信息**。我嘗試了很多在spring參考手冊中給出的切入點,但是可悲的是,沒有人爲我工作。 我使用Logging中的切入點表達式問題,使用log4j的Spring AOP

@Pointcut("execution(* com.mycomp..(..))") 
private void businessService() {} // signature 

我所得到的是

Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 
'name pattern cannot finish with ..' at character position 27 
execution(* com.mycomp..(..)) 

在文檔中,因爲

@Pointcut("execution(com.xyz.someapp..service..(..))") 

我一直在使用執行(com.mycomp。(試過。 。))但有類似的例外。

按照James的建議,在使用切入點@Around(value =「execution(* xyz.package.foo.bar .. *(..))」)時,我在啓動服務器時遇到新的異常。

Caused by: java.lang.IllegalStateException: Cannot convert value of type [$Proxy76 implementing org.springframework.context.ApplicationContextAware,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.mycompname.BancsContextAware] for property 'bancsContextAware': no matching editors or conversion strategy found 
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:264) 
at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:448) 
... 57 more 

後來調試我發現,在類中的一個我使用object.getClass()。getAnnotation()並且其通過彈簧AOP創建不具有註釋代理對象。因爲只有我得到一個空指針異常。我整理,使用AopProxyUtils.ultimateTargetClass(s​​omeObject) 但現在的問題是,我有com.mycom ..因爲這樣子包內最後的一些類和枚舉我得到

nested exception is org.springframework.aop.framework.AopConfigException: 
Could not generate CGLIB subclass of class [class com.mycom.util.BancsServiceProvider]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.mycom.util.BancsServiceProvider 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529) 

那麼如何排除Spring AOP切入點的最終類和枚舉。

回答

2

你正在尋找的切入點和方法是這樣的:

@Around(value="execution(* xyz.package.foo.bar..*(..))") 
public Object beforeAdvice(ProceedingJoinPoint jp) throws Throwable { 
    //Get log4j logger for target class. 
    Logger logger = LogManager.getLogger(jp.getTarget().getClass()); 

    logger.info(jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " " 
      + "Hit:"); 
    Object returnVal = jp.proceed(jp.getArgs()); 
    logger.info(jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " " 
      + "Finished:"); 
    return returnVal; 
} 

上面的代碼將記錄類和方法的名稱,以及「重災區」在進入方法之前和「完成」一次它是通過以下方式進行:

xyz.package.foo.bar.service.getPerson: Hit: 
xyz.package.foo.bar.dao.getPerson: Hit: 
xyz.package.foo.bar.dao.getPerson: Finished: 
xyz.package.foo.bar.service.getPerson: Finished: 
... 

如果你想嘗試按照方法多線程執行,只需使用以下命令:

@Around(value="execution(* xyz.package.foo.bar..*(..))") 
public Object beforeAdvice(ProceedingJoinPoint jp) throws Throwable { 
    Logger logger = LogManager.getLogger(jp.getTarget().getClass()); 

    String executionId = UUID.randomUUID().toString(); 

    logger.info(jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " " 
      + "Hit:" + executionId); 
    Object returnVal = jp.proceed(jp.getArgs()); 
    logger.info(jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " " 
      + "Finished:" + executionId); 
    return returnVal; 
} 

您將得到每個線程調用的UUID,這將允許您跟蹤這些方法在所有線程中執行的速度。我在嘗試獲取性能測試的方法時間時使用此代碼,並且它可以創造奇蹟。

請確保您已將該類聲明爲一個方面。

0

您是否嘗試過以下方法?

@Pointcut(「within(com.mycomp .. *)」)