2012-10-18 168 views
3

我有一個Java類,這是類似以下內容:Spring:春天訪問的spring對象中是否有私人創建的對象?

public class Foo{ 
    public void doSomething(){ 
    StageA a = new StageA(); 
    StageB b = new StageB(); 
    StageC c = new StageC(); 
    a.execute(); 
    b.execute(); 
    c.execute(); 
    } 
} 

現在,假設我真的不能修改這個類本身,可能我還是用Spring AOP的申請登錄aroundexecute方法? (大概沒有使用aspect4j

回答

1

是的,你可以按照如下用execution切入點定位方法,其名稱是​​寫@Around建議:

@Around("execution(* execute(..))") 
public Object execute(ProceedingJoinPoint pjp) throws Throwable 
{ 
    // Log statements before the call; 

    Object obj = pjp.proceed(); 

    // Log statements after the call; 

    return obj; 
} 
+0

它可以用於非彈簧管理對象嗎?據我所知,spring在bean周圍創建一個代理,所以它實際上是調用代理而不是實際的對象本身 – goh

+1

它只適用於spring管理的對象。您可以使用'@ Configurable'註釋來限定Stage對象,這樣即使您使用'new'運算符創建對象,它們也可以進行彈簧管理。然後'@ Around'方面將在執行方法上工作。 – Vikdor

2

那麼你可以記錄方法,它是所需的時間(對於性能),但我不認爲你將能夠記錄什麼方法正在做。

Spring Docs

Around通知:包圍一個連接點,如方法調用的建議。這是最強有力的建議。周圍的建議可以在方法調用之前和之後執行自定義行爲。它還負責選擇是繼續加入連接點還是通過返回其自身的返回值或拋出異常來快速建議的方法執行。


如果您正在使用log4j的記錄器在內部你的方法,你可以登錄什麼方法是通過配置的log4j做。

(可能不使用aspect4j)

- >彈簧內部使用aspectJ

檢查here參考,例如

2

編輯: 我不認爲您可以在您的案例中記錄每個「execute」方法的執行情況,而無需更改Foo或Stage類。因爲Stage ...類不是由容器管理的。只有在doSomething方法開始執行時(如果Foo類由Spring容器管理),才能記錄日誌,但無法控制它的執行流。

如果你的類是由Spring容器管理的,那麼你可以輕鬆地做到這一點。您應該簡單地爲Stage ...類編寫Spring AOP「around」方面,而不是Foo類。

下面是簡單的日誌記錄方面的一個例子:

@Component 
@Aspect 
@Order(value=2) 
public class LoggingAspect { 

    @Around("execution(* com.blablabla.server..*.*(..))") 
    public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable{ 
     final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName()); 
     Object retVal = null; 

     try { 
      StringBuffer startMessageStringBuffer = new StringBuffer(); 

      startMessageStringBuffer.append("Start method "); 
      startMessageStringBuffer.append(joinPoint.getSignature().getName()); 
      startMessageStringBuffer.append("("); 

      Object[] args = joinPoint.getArgs(); 
      for (int i = 0; i < args.length; i++) { 
       startMessageStringBuffer.append(args[i]).append(","); 
      } 
      if (args.length > 0) { 
       startMessageStringBuffer.deleteCharAt(startMessageStringBuffer.length() - 1); 
      } 

      startMessageStringBuffer.append(")"); 

      logger.trace(startMessageStringBuffer.toString()); 

      StopWatch stopWatch = new StopWatch(); 
      stopWatch.start(); 

      retVal = joinPoint.proceed(); 

      stopWatch.stop(); 

      StringBuffer endMessageStringBuffer = new StringBuffer(); 
      endMessageStringBuffer.append("Finish method "); 
      endMessageStringBuffer.append(joinPoint.getSignature().getName()); 
      endMessageStringBuffer.append("(..); execution time: "); 
      endMessageStringBuffer.append(stopWatch.getTotalTimeMillis()); 
      endMessageStringBuffer.append(" ms;"); 

      logger.trace(endMessageStringBuffer.toString()); 
     } catch (Throwable ex) { 
      StringBuffer errorMessageStringBuffer = new StringBuffer(); 

      // Create error message 
      logger.error(errorMessageStringBuffer.toString(), e) 

      throw ex; 
     } 

     return retVal; 
    } 
} 
+0

如何將我寫的Stage類的方面,如果它們不是由Spring容器管理的? – goh

+0

對不起,愚蠢的錯誤。您不能爲不受容器管理的類編寫Spring AOP方面。這是你的情況。我現在會想另一種方式來做到這一點。 – dimas

+0

我不認爲有可能在你的情況下記錄執行每個「execute」方法而不改變Foo類。因爲Stage ...類不是由容器管理的。只有當doSomething mwthod將開始執行時(如果Foo類由Spring容器管理),您才能記錄,但無法控制它的執行流。 – dimas