Java 包内所有方法的@AspectJ 切入点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25992277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 01:38:53  来源:igfitidea点击:

@AspectJ pointcut for all methods inside package

javaspringaopaspectjspring-aop

提问by Mohan Seth

I have this working code for a specific package, but i want to configure it for all controllers, serviceand daopackages Eg

我有一个特定包的工作代码,但我想为所有控制器服务dao包配置它,例如

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

and so on. . . that is the base package of my project, can someone please help how I can go about doing it so that it works for all classes of my web project including controllers, thanks in advance. . .

等等。. . 这是我的项目的基本包,有人可以帮助我如何去做,以便它适用于我的网络项目的所有类,包括控制器,在此先感谢。. .

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

}

采纳答案by kriegaex

How about one of these alternatives?

这些替代方案之一怎么样?

A) General execution pointcut with package restrictions:

A) 具有包限制的通用执行切入点:

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

B) Package-restricted execution pointcuts:

B) 包限制的执行切入点:

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

I prefer B, by the way, just because it is a bit shorter and easier to read. As you have probably guessed, the ..notation means "any package or subpackage", whereas *at the end of the expression after ..means "any method in any class".

顺便说一下,我更喜欢 B,因为它更短更容易阅读。正如您可能已经猜到的那样,该..表示法的意思是“任何包或子包”,而*表达式末尾的 after..表示“任何类中的任何方法”。

回答by Vimal Bera

You just need to change your point cut to something like this :

您只需要将切入点更改为如下所示:

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

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

进一步阅读 - https://docs.spring.io/spring/docs/2.0.x/reference/aop.html

回答by ryzhman

Another alternative is to use

另一种选择是使用

@Pointcut("bean(*Controller)")

But naming of your beans should be corresponding

但是你的bean的命名应该是对应的