2014-09-23 8 views
16

Ich habe diese Arbeit Code für ein bestimmtes Paket, aber ich will es so konfigurieren, für alle Controller, Service und dao Pakete Eg@AspectJ pointcut für alle Methoden in der Verpackung

  • 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

und so weiter. . . das ist das Basispaket meines Projekts, kann jemand bitte helfen, wie ich es tun kann, so dass es für alle Klassen meines Webprojekts einschließlich Controller funktioniert, danke im Voraus. . .

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

} 

Antwort

35

Wie wäre eine dieser Alternativen?

A) Allgemeine Ausführung pointcut mit Paket Einschränkungen:

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

B) Paket-restricted Ausführung pointcuts:

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

Ich ziehe B, nebenbei bemerkt, ist es nur, weil ist ein bisschen kürzer und einfacher zu lesen. Wie Sie wahrscheinlich schon erraten haben, bedeutet die Schreibweise .. "beliebiges Paket oder Unterpaket", während * am Ende des Ausdrucks nach .. "irgendeine Methode in irgendeiner Klasse" bedeutet.

+0

Also im Prinzip ist es möglich, alle 'innerhalb()' Punktausdrücke mit anderen Pointcut-Desginatoren zu definieren, oder? Ich denke, für verschachtelte Klassen kann 'inter()' die Ausdrücke vereinfachen (manchmal _extremely_), aber ansonsten ist es nur ein praktischer Pointcut-Bezeichner. – Behrang

+0

Theoretisch ja, aber es macht oft einfach keinen Sinn. Ich würde immer die (Kombination von) Pointcut (s) wählen, die meine Absicht als Entwickler am deutlichsten ausdrücken. Gute Pointcuts können wie ein Satz gelesen werden: "Wählen Sie in den Paketen x und y alle öffentlichen, nicht statischen Methoden in Klassen aus, die mit @Z annotiert sind, aber nur, wenn sie Werte vom Typ A zurückgeben." – kriegaex

4

Sie müssen genau wie dies Ihr Punkt schneiden, um etwas zu ändern:

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

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

+0

Hallo, danke für die Antwort werden entsprechende, aber es funktioniert nicht für meine Controller –

+1

Okay. Für Controller können Sie etwas wie http://stackoverflow.com/questions/2011089/aspectj-pointcut-for-all-methods-of-a-class-with-specific-annotation –

+0

Keine Zuordnung für HTTP-Anfrage mit URI gefunden [ /xyz-web-vodafone/content.showContentWorkbench.htm] in DispatcherServlet mit dem Namen 'Dispatcher' –

0

Eine weitere Alternative ist

@Pointcut("bean(*Controller)") 

Aber Benennung Ihrer Bohnen verwenden sollten

Verwandte Themen