2014-09-23 13 views
16

Mam ten kod pracy dla konkretnego pakietu, ale chcę skonfigurować go dla wszystkich kontrolerów, usługowa i dao pakiety Np@AspectJ punktu przekroju dla wszystkich metod wewnątrz pakietu

  • com .abc.xyz.content.controller
  • com.abc.xyz.content.service
  • com.abc.xyz.content.dao
  • com.abc.x yz.category.controller
  • com.abc.xyz.category.service
  • com.abc.xyz.category.dao

i tak dalej. . . który jest podstawowym pakietem mojego projektu, czy ktoś może pomóc, jak mogę to zrobić, aby działał na wszystkie klasy mojego projektu internetowego, w tym kontrolerów, z góry dziękuję. . .

package com.abc.xyz.utilities; 

import java.util.Arrays; 

import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.AfterReturning; 
import org.aspectj.lang.annotation.AfterThrowing; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Before; 
import org.aspectj.lang.annotation.Pointcut; 
import org.springframework.core.annotation.Order; 
import org.springframework.stereotype.Component; 

@Aspect 
@Component 
public class LoggingAspect 
{ 
    private Log log = LogFactory.getLog(this.getClass()); 

    @Pointcut("execution(* com.abc.xyz.content.service..*(..))") 
    protected void loggingOperation() 
    { 
    } 

    @Before("loggingOperation()") 
    @Order(1) 
    public void logJoinPoint(JoinPoint joinPoint) 
    { 
    log.info("Signature declaring type : " + joinPoint.getSignature().getDeclaringTypeName()); 
    log.info("Signature name : " + joinPoint.getSignature().getName()); 
    log.info("Arguments : " + Arrays.toString(joinPoint.getArgs())); 
    log.info("Target class : " + joinPoint.getTarget().getClass().getName()); 
    } 

    @AfterReturning(pointcut = "loggingOperation()", returning = "result") 
    @Order(2) 
    public void logAfter(JoinPoint joinPoint, Object result) 
    { 
    log.info("Exiting from Method :" + joinPoint.getSignature().getName()); 
    log.info("Return value :" + result); 
    } 

    @AfterThrowing(pointcut = "execution(* com.abc.xyz.content.service..*(..))", throwing = "e") 
    @Order(3) 
    public void logAfterThrowing(JoinPoint joinPoint, Throwable e) 
    { 
    log.error("An exception has been thrown in " + joinPoint.getSignature().getName() + "()"); 
    log.error("Cause :" + e.getCause()); 
    } 

    @Around("execution(* com.abc.xyz.content.service..*(..))") 
    @Order(4) 
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable 
    { 
    log.info("The method " + joinPoint.getSignature().getName() + "() begins with " + Arrays.toString(joinPoint.getArgs())); 
    try 
    { 
     Object result = joinPoint.proceed(); 
     log.info("The method " + joinPoint.getSignature().getName() + "() ends with " + result); 
     return result; 
    } 
    catch (IllegalArgumentException e) 
    { 
     log.error("Illegal argument " + Arrays.toString(joinPoint.getArgs()) + " in " + joinPoint.getSignature().getName() + "()"); 
     throw e; 
    } 
    } 

} 

Odpowiedz

35

Jak o jednej z tych alternatyw?

A) Ogólne punktu przekroju wykonanie z ograniczeniami pakiet:

execution(* *(..)) && 
(
    within(com.abc.xyz..controller..*) || 
    within(com.abc.xyz..service..*) || 
    within(com.abc.xyz..dao..*) 
) 

B) Pakiet-ograniczone punkty przekroju wykonanie:

execution(* com.abc.xyz..controller..*(..)) || 
execution(* com.abc.xyz..service..*(..)) || 
execution(* com.abc.xyz..dao..*(..)) 

Wolę B, nawiasem mówiąc, właśnie dlatego, że jest nieco krótszy i łatwiejszy do odczytania. Jak zapewne się domyślacie, notacja .. oznacza "dowolny pakiet lub podpakiet", podczas gdy * na końcu wyrażenia po .. oznacza "dowolną metodę w dowolnej klasie".

+0

Więc zasadniczo możliwe jest zdefiniowanie wszystkich wyrażeń 'within()' używając innych deskryptorów punktów, prawda? Myślę, że dla klas zagnieżdżonych, 'within()' może uprościć wyrażenia (czasami _extremely_), ale poza tym jest to tylko wygodny desygnator punktów. – Behrang

+0

Teoretycznie tak, ale często po prostu nie ma sensu. Zawsze wybrałbym (kombinację) wycinków, wyraźnie wyrażających moje zamiary jako programisty. Dobre przekreślenia można odczytywać jak zdania takie jak: "W pakietach x i y wybierz wszystkie publiczne, niestatyczne metody w klasach z adnotacjami @Z, ale tylko wtedy, gdy zwracają wartości typu A." – kriegaex

4

Trzeba tylko zmienić punkt cięcia coś takiego:

@Pointcut("within(com.abc.*)") 

Dalsze czytania - https://docs.spring.io/spring/docs/2.0.x/reference/aop.html

+0

Witam, dzięki za odpowiedź, ale nie robi praca dla moich kontrolerami –

+1

Ok. W przypadku kontrolerów można zrobić coś takiego jak http://stackoverflow.com/questions/2011089/aspectj-pointcut-for-all-metod--class-w-specific-annotation –

+0

Nie znaleziono mapowania dla żądania HTTP z identyfikatorem URI [ /xyz-web-vodafone/content.showContentWorkbench.htm] w DispatcherServlet z nazwą 'dispatcher' –

0

Inną alternatywą jest użycie

@Pointcut("bean(*Controller)") 

Ale nazywanie swoich fasoli powinny być odpowiadające

Powiązane problemy