2017-03-08 10 views
2

Ich loggen Methode Eingabe und Ausgabe von Parametern durch einen einfachen Aspekt.Spring AOP Logging und Cache

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; 
    } 
} 

, die durch diese Anmerkung angefügt wird.

package com.mk.cache; 

public @interface LoggedIO { 

} 

I verwenden diesen Mechanismus Ein- und Ausgänge von Methoden wie diese einzuloggen (bemerkt @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; 
    } 
} 

I auch Frühlings-Cache verwenden. Hier ist die Beispielanwendung.

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)); 
    } 
} 

Die Ausgabe sieht wie folgt aus:

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

Mein Problem ist, dass, wenn ich LOGGER.info("cachedService.getInt(1)={}", cachedService.getInt(1)); zum zweiten Mal aufrufen, wird die im Cache gespeicherten Wert verwendet, aber die Ein- und Ausgangsparameter sind nicht angemeldet, als der Cache ist der erste Wrapper. Ist es möglich, LoggingAspect irgendwie als den ersten Wrapper zu konfigurieren, so dass ich sowohl die AOP-Protokollierung als auch den Spring Cache verwenden kann?

+0

betrachten Sie dies http://stackoverflow.com/questions/39047520/how-to-make-spring-cacheable-work-on-top-of-aspectj-aspect – reos

Antwort

2

Gerade Frühjahr bestellt Schnittstelle implementieren und in getOrder() -Methode Rückkehr 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 mehr lesen. Kapitel 11.2.7