@AspectJ切入点,用于包含关键字服务

时间:2016-05-20 05:16:55

标签: aspectj spring-aop

我试图拦截包名中包含特定单词的所有类...如下所示:

@Pointcut("execution(* *..service..*.*(..))")

我有包中的所有类来拦截:

com.domain.model.user.service.save(User user);
com.domain.model.user.service.impl.save(XPTO xpto);
com.domain.model.foo.service.HelloWorld.getMessage(Foo foo);

简而言之,我想拦截属于

的类中的所有方法
package *service*

我试图让这项工作从过去很多天开始。

3 个答案:

答案 0 :(得分:0)

试试这个。也许您必须排除方面类以避免无限循环。此示例使用包中的com..login .. *捕获所有方法

@Aspect
@SuppressAjWarnings({ "adviceDidNotMatch" })
public class AllMethodsAspect {
    private static Map<String, Long> beforeTimestamps = new HashMap<>();

    @Pointcut("!within(aspects..*)"
                    + " && (!execution(* org..*           (..))     && !within(org..*)           && !call(* org..*         (..)) )"
                    + " && (!execution(* java..*          (..))     && !within(java..*)          && !call(* java..*        (..)) )"
                    + " && (!execution(* javax..*         (..))     && !within(javax..*)         && !call(* javax..*       (..)) )"
                    + " && (!execution(* sun..*           (..))     && !within(sun..*)           && !call(* sun..*         (..)) )"
                    + " && execution(* com..login..*(..))")
    public void methodCall() {
    }

    @Before("methodCall()")
    public void before(JoinPoint joinPoint) {
        beforeMethodCall(joinPoint);
    }

    @AfterReturning(pointcut = "methodCall()", returning = "returnObject")
    public void after(JoinPoint joinPoint, Object returnObject) {
        afterMethodCall(joinPoint, returnObject);
    }

    @AfterThrowing(pointcut = "methodCall()", throwing = "throwable")
    public void throwing(JoinPoint joinPoint, Throwable throwable) {
        afterThrowingMethodCall(joinPoint, throwable);
    }

    void beforeMethodCall(JoinPoint joinPoint) {
        try {
            long start = System.currentTimeMillis();
            beforeTimestamps.put(joinPoint.toString() + " - " + Thread.currentThread().getName(), Long.valueOf(start));
            LOG.info(".before " + joinPoint);
        } catch (Exception e) {
            LOG.error(".before Exception " + e);
        }
    }

    void afterMethodCall(JoinPoint joinPoint, Object returnObject) {
        afterMethodCall(joinPoint, returnObject, 0);
    }

    void afterMethodCall(JoinPoint joinPoint, Object returnObject, int depth) {
        try {
            long start = beforeTimestamps.get(joinPoint.toString() + " - " + Thread.currentThread().getName()).longValue();
            beforeTimestamps.remove(joinPoint.toString() + " - " + Thread.currentThread().getName());

            long duration = System.currentTimeMillis() - start;
            Signature signature = joinPoint.getSignature();
            if (signature instanceof MethodSignature) {
                Class<?> returnType = ((MethodSignature) signature).getReturnType();
                LOG.info(".after " + joinPoint + " " + duration + "ms" + (void.class == returnType ? "" : " [" + returnObject + "]"));
            } else if (signature instanceof ConstructorSignature) {
                LOG.info(".after " + joinPoint + " " + duration + "ms Constructor");
            } else if (signature instanceof FieldSignature) {
                LOG.info(".after " + joinPoint + " " + duration + "ms Field");
            } else {
                LOG.info(".after " + joinPoint + " " + duration + "ms unknown");
            }
        } catch (Exception e) {
            LOG.error(".after Exception " + e);
        }
    }

    void afterThrowingMethodCall(JoinPoint joinPoint, Throwable throwable) {
        try {
            Long startAsLong = beforeTimestamps.get(joinPoint.toString() + " - " + Thread.currentThread().getName());
            long start = startAsLong == null ? 0 : startAsLong.longValue();
            beforeTimestamps.remove(joinPoint.toString() + " - " + Thread.currentThread().getName());

            long duration = System.currentTimeMillis() - start;
            LOG.info(".fail " + joinPoint.toString() + " " + duration + " ms - " + throwable.getMessage());
        } catch (NullPointerException e) {
            LOG.info(".fail NullPointerException " + "unknown - " + throwable.getMessage());
        }
    }

    static final class LOG {
        static void info(String loggingData) {
            System.err.println(new Date() + " " + loggingData);
        }

        static void error(String loggingData) {
            System.err.println(new Date() + " " + loggingData);
        }
    }
}

答案 1 :(得分:0)

我认为你可以用这样的切入点捕获你需要的东西:

before(): execution(* *(..)) && 
          (within(*..service..*.*) || within(service..*.*) || within(*..service.*)) {}

这三个条款涵盖了三个选择:

  • within(*..service..*.*):'service'位于包名称的某处,但不在开头或结尾
  • within(service..*.*):'service'位于包名称的开头(可能在您的方案中不会发生)
  • within(*..service.*)):'service'位于包名称的末尾

如果您需要捕获serviceFoo变体,可以在服务周围添加更多通配符(我认为):within(*..*service*.*)

答案 2 :(得分:0)

你应该使用这样的切入点表达式:

within(your.base.package..service..*)
  • 至少限制你的基础包(通常这不是问题)
  • 匹配&#39;服务&#39;任何级别的包名称中的关键字
例如,

将匹配这些类:

  • your.base.package.service.ServiceClass
  • your.base.package.service.customer.ServiceClass
  • your.base.package.internal.service.ServiceClass
  • your.base.package.internal.service.customer.ServiceClass