2014-09-23 16 views
16

ho questo codice di lavoro per un pacchetto specifico, ma voglio configurarlo per tutti i controller , servizio e Dao pacchetti Eg@AspectJ pointcut per tutti i metodi all'interno del pacchetto

  • 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

e così via. . . che è il pacchetto base del mio progetto, qualcuno può per favore aiutare come posso fare in modo che funzioni per tutte le classi del mio progetto web compresi i controller, grazie in anticipo. . .

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

} 

risposta

35

Come su una di queste alternative?

A) Generale pointcut esecuzione con restrizioni del pacchetto:

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

B) pointcut esecuzione del pacchetto-ristrette:

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

preferisco B, tra l'altro, proprio perché è un po 'più breve e più facile da leggere. Come probabilmente avete intuito, la notazione .. significa "qualsiasi pacchetto o sotto pacchetto", mentre * alla fine dell'espressione dopo .. significa "qualsiasi metodo in qualsiasi classe".

+0

Quindi, in pratica, è possibile definire tutte le espressioni di pointcut 'all'interno()' usando altri desginatori di punti, giusto? Penso che per le classi annidate, 'within()' può semplificare le espressioni (a volte _estremamente_), ma altrimenti è solo un conveniente designatore di punti. – Behrang

+0

Teoricamente sì, ma spesso non ha senso. Sceglierei sempre la (combinazione di) punti (i) che più chiaramente esprimono il mio intento come sviluppatore. I buoni punti possono essere letti come una frase come: "All'interno dei pacchetti xey, scegli tutti i metodi pubblici, non statici nelle classi annotate da @Z, ma solo se restituiscono i valori di tipo A." – kriegaex

4

Hai solo bisogno di cambiare il vostro taglio puntare a qualcosa di simile:

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

Ulteriori letture - https://docs.spring.io/spring/docs/2.0.x/reference/aop.html

+0

Ciao, grazie per la risposta, ma doesnt lavoro per i miei controllori –

+1

Va bene. Per i controller puoi fare qualcosa come http://stackoverflow.com/questions/2011089/aspectj-pointcut-for-all-methods-of-a-class-with-specific-annotation –

+0

Nessun mapping trovato per la richiesta HTTP con URI [ /xyz-web-vodafone/content.showContentWorkbench.htm] in DispatcherServlet con nome 'dispatcher' –

0

Un'altra alternativa è quella di utilizzare

@Pointcut("bean(*Controller)") 

Ma denominazione dei vostri fagioli deve essere corrispondente