2017-03-08 115 views
2

我是通過一個簡單的方面記錄方法的輸入和輸出參數。Spring AOP日誌記錄和緩存

package com.mk.cache; 

import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.stereotype.Component; 

import java.util.Arrays; 

@Aspect 
@Component 
public class LoggingAspect { 
    @Around("within(@com.mk.cache.LoggedIO *) && execution(* *(..))") 
    public Object logAroundPublicMethod(ProceedingJoinPoint joinPoint) throws Throwable { 
     String wrappedClassName = joinPoint.getSignature().getDeclaringTypeName(); 
     Logger LOGGER = LoggerFactory.getLogger(wrappedClassName); 
     String methodName = joinPoint.getSignature().getName(); 
    LOGGER.info("LOG by AOP - invoking {}({})", methodName, Arrays.toString(joinPoint.getArgs())); 
    Object result = joinPoint.proceed(); 
    LOGGER.info("LOG by AOP - result of {}={}", methodName, result); 
     return result; 
    } 
} 

本附註附加。

package com.mk.cache; 

public @interface LoggedIO { 

} 

我使用此機制來記錄輸入和的這樣的方法的輸出(通知@LoggedIO):

package com.mk.cache; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.cache.annotation.Cacheable; 
import org.springframework.stereotype.Service; 

@Service 
@LoggedIO 
public class CachedService { 

    private static final Logger LOGGER = LoggerFactory.getLogger(CachedService.class); 

    @Cacheable("myCacheGet") 
    public int getInt(int input) { 
     LOGGER.info("Doing real work"); 
     return input; 
    } 
} 

我也使用Spring緩存。這是示例應用程序。

package com.mk.cache; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.CommandLineRunner; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.cache.annotation.EnableCaching; 

@SpringBootApplication 
@EnableCaching 
public class CacheApplication implements CommandLineRunner { 

    private static final Logger LOGGER = LoggerFactory.getLogger(CacheApplication.class); 

    public static void main(String[] args) { 
     SpringApplication.run(CacheApplication.class, args); 
    } 

    @Autowired 
    private CachedService cachedService; 

    @Override 
    public void run(String... args) throws Exception { 
     LOGGER.info("cachedService.getInt(1)={}", cachedService.getInt(1)); 
     LOGGER.info("cachedService.getInt(1)={}", cachedService.getInt(1)); 
    } 
} 

輸出看起來是這樣的:

LOG by AOP - invoking getInt([1]) 
Doing real work 
LOG by AOP - result of getInt=1 
cachedService.getInt(1)=1 
cachedService.getInt(1)=1 

我的問題是,當我打電話LOGGER.info("cachedService.getInt(1)={}", cachedService.getInt(1));第二次,緩存的值被使用,但輸入和輸出參數還沒有登錄,因爲緩存是第一個包裝。是否有可能以某種方式將LoggingAspect配置爲第一個包裝,因此我將能夠同時使用AOP日誌記錄和兩個Spring Cache?

+0

看看這個http://stackoverflow.com/questions/39047520/how-to-make-spring-cacheable-work-on-top-of-aspectj-aspect – reos

回答

2

只實現有序春界面和getOrder()方法返回1

@Aspect 
@Component 
public class LoggingAspect implements Ordered { 
    @Around("within(@com.mk.cache.LoggedIO *) && execution(* *(..))") 
    public Object logAroundPublicMethod(ProceedingJoinPoint joinPoint) throws Throwable { 
     String wrappedClassName = joinPoint.getSignature().getDeclaringTypeName(); 
     Logger LOGGER = LoggerFactory.getLogger(wrappedClassName); 
     String methodName = joinPoint.getSignature().getName(); 
    LOGGER.info("LOG by AOP - invoking {}({})", methodName, Arrays.toString(joinPoint.getArgs())); 
    Object result = joinPoint.proceed(); 
    LOGGER.info("LOG by AOP - result of {}={}", methodName, result); 
     return result; 
    } 

    @Override 
    public int getOrder() { 
     return 1; 
    } 

} 

更多here。章11.2.7