【问题标题】:How do I access parameters specified in a Java Aspect?如何访问 Java 特性中指定的参数?
【发布时间】:2015-05-30 03:51:02
【问题描述】:

我有一个名为“@ProgressCheck”的注释,我们可以将它放在控制器上以检查应用程序的进度。如果应用程序已经提交或延迟提交,那么它会将用户带到适合该情况的页面。

注解界面为:

@Retention(RetentionPolicy.RUNTIME)
public @interface ProgressCheck {
}

该注释的“实现”类似于:

@Around("execution(* *(..)) && args(session,..) && @annotation(com.foo.aspects.progress.ProgressCheck)")
public Object progressCheck(ProceedingJoinPoint pjp, HttpSession session) throws Throwable {

    Applicant applicant = this.applicationSessionUtils.getApplicant(session);
    Application application = this.applicationSessionUtils.getApplication(session);

    switch (this.applicantService.getProgress(applicant)) {
    case SUBMITTED:
        return this.modelAndViewFactory.gotoStatusPage(applicant, application);

    case LATE:
        return this.modelAndViewFactory.gotoDeadlineMissed(applicant, application);

    default:
    case IN_PROGRESS:
        return pjp.proceed();
    }
}

根据会话和数据库中的值,注释的“实现”允许用户继续进入控制器,或根据需要将它们重定向到另一个 ModelAndView。

我想为注释提供参数,然后在这个“实现”逻辑中,使用这些参数来进一步调整决策。从这个逻辑来看,在不知道注释应用在哪里的情况下,我如何访问这些参数?还是我应该使用另一种方法?

【问题讨论】:

  • 使用注解中定义的访问器方法?
  • 我认为另一个问题与我所问的不同。如果我没记错的话,该问题涉及已注释的方法,并获取在该特定实例中分配给注释的值。我想写一个接受参数的注解,并根据这些参数实现注解来做一些事情。
  • 你是什么意思实现注释做某事?注释不做任何事情。它只是元数据。有注释处理器基于该元数据执行逻辑。副本解释了如何获取该元数据。也就是说,它解释了如何从从某个带注释的成员(例如方法)检索到的Day 类型的实例调用dayNames。如果这不是您的问题,请澄清。
  • @biziclop:对不起,但这对我来说是新的。不知道你说的是什么方法。你能指出一些解释它的东西或提供一个例子吗?
  • 可能想看看Proxy 类。注释只是@Secured 行为实现的一小部分。

标签: java reflection annotations aop


【解决方案1】:

诀窍是查询方面的 JoinPoint 对象以获取有关被注释的方法(或类或其他)的注释信息。那是我想不出来的胶水。

这是一个例子。一是方面的接口。此注解只会应用于方法。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DayOfWeek {

    public String[] names();

}

现在实现方面:

@Aspect
public class DayOfWeekAspect {

    public DayOfWeekAspect() {
    }

    @Around("execution(* *(..)) && args(session,..) && @annotation(edu.berkeley.jazztwo.aspect.ams.roles.DayOfWeek)")
    public Object dayOfWeek(ProceedingJoinPoint joinPoint, HttpSession session) throws Throwable {

        String[] names = this.getNames(this.getAnnotatedMethod(joinPoint));

        for (String name : names) {
            System.out.println("DayOfWeek:   " + name);
        }

        // Do whatever you want with the aspect parameters
        if (checkSomething(names)) {
            // in some cases, go to a different view/controller
            return new ModelAndView(...);
        }

        // Just proceed into the annotated method
        return joinPoint.proceed();
    }

    private Method getAnnotatedMethod(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        return methodSignature.getMethod();
    }

    private String[] getNames(Method method) {
        DayOfWeek aspect = method.getAnnotation(DayOfWeek.class);
        if (aspect != null) {
            return aspect.names();
        }
        return new String[0]; // no annotation, return an empty array
    }
}

然后将方面应用到某个方法

@DayOfWeek(names = {"Monday", "Wednesday", "Friday"})
@RequestMapping(value = "foo", method = RequestMethod.GET)
public ModelAndView foo(...) {
    ...
}

然后,如果你像我一样,你会挠头,想知道为什么它不起作用。您终于记得(如果您使用 XML 配置)您必须在配置中的某处实例化 bean:

<bean id="dayOfWeekAspect" class="com.foo.bar.DayOfWeekAspect" />     

那么您可以调用 foo,它应该会打印出星期一、星期三和星期五。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 2016-06-28
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    相关资源
    最近更新 更多