有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

spring获得了一个模板/通用java。朗,反思一下。组织中的方法对象。aspectj。lang.ProceedingJoinPoint

如果AspectJ的工作方式与EJB拦截器的工作方式相同,那么这个问题就不存在了

考虑基本场景EJB拦截器方式:

@AroundInvoke
public Object log(final InvocationContext ctx) throws Exception {
    // do stuff before
    final Object result = ctx.proceed();
    // do stuff after
    return result;
}

现在我需要被拦截的方法对象。在这里,我可以简单地做到:

        Method method = ctx.getMethod();

就这样,在这之后,我将检查截取方法的注释

现在我正在使用部署到servlet容器(Tomcat)的应用程序,因此没有EJB。其中的AOP是使用Spring+AspectJ实现的

around方法如下所示:

@Around("execution(* foo.bar.domain.integration.database.dao..*(..))")
public Object log(final ProceedingJoinPoint pjp) throws Throwable {
    // do stuff before
    final Object result = pjp.proceed();
    // do stuff after
    return result;
}

在这里,我不能再这样做了:

Method method = pjp.getMethod(); // no such method exists

取而代之的是,我被迫自己使用反射获取方法对象,如下所示:

    final String methodName = pjp.getSignature().getName();
    final Object[] arguments = pjp.getArgs();
    final Class[] argumentTypes = getArgumentTypes(arguments);
    final Method method = pjp.getTarget().getClass().getMethod(methodName, argumentTypes);

在您想要掌握模板方法之前,它一直有效:

@Transactional
public <T extends Identifiable> T save(T t) {
    if (null == t.getId()) {
        create(t);
        return t;
    }
    return update(t);
}

假设您按如下方式调用此方法:

Person person = new Person("Oleg");
personService.save(person);

您将收到:

Caused by: java.lang.NoSuchMethodException: foo.bar.domain.integration.database.dao.EntityService.save(foo.bar.domain.entity.Person)

这是由:

pjp.getTarget().getClass().getMethod()

问题是运行时不存在泛型,实际的方法签名是:

public Identifiable save(Identifiable t) {}

最终类[]argumentTypes将包含一个元素,其类型将为Person。所以这个电话:

pjp.getTarget().getClass().getMethod(methodName, argumentTypes);

将查找方法:

save(Person p)

而且找不到

所以问题是:如何获得java的模板方法对象的实例,该对象表示被截取的确切方法

我想其中一种方法就是用蛮力的方式: 获取参数超类/接口,并尝试使用这些类型获取方法,直到不再获得NoSuchMethodException,但这显然很难看。有没有一个正常的清洁方式可以做到这一点


共 (1) 个答案

  1. # 1 楼答案

    MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
    Method targetMethod = methodSignature.getMethod();
    

    这一点并不明显,这要归咎于API

    另见Spring AOP: how to get the annotations of the adviced method。我自己还没有测试过。那里的工作人员说,这为他解决了这个问题。对于另一种用途,需要额外的@Around(annotation...)注释。(例如,尝试将目标设置为仅METHOD,并查看其行为)