qwerty1423
qwerty1423

Reputation: 303

Spring AOP: Advice on annotation used over another advice

I have created my custom annotation:

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Condition {
    String value();
}

I want to use this annotation to determine whether or not to run advice, my try:

@Condition("some.config")
@Around("execution(public * someMethod())")
Object doSomething(ProceedingJoinPoint joinPoint) throws Throwable {
    // some logic here
}

@Around("@annotation(condition)")
Object checkCondition(ProceedingJoinPoint joinPoint, Condition condition) throws Throwable {
    String property = (String) configuration.getProperty(condition.value());
    if (Boolean.valueOf(property)){
        return joinPoint.proceed();
    } else {
        return null;
    }
}

It works when I use @Condition on some other methods, i.e. the checkCondition is applied and then the method is executed or not based on config value. For advice doSomething it doesn't get applied though.

Upvotes: 0

Views: 875

Answers (1)

kriegaex
kriegaex

Reputation: 67387

You said your aspect works for other components, just not the aspect itself. From this statement I gather that

  1. your aspect is wired correctly (e.g. annotated with @Component and detected by component scan or wired manually via XML config) and
  2. you use proxy-based Spring AOP.

In (2) is the source of your problem. According to the Spring manual aspects themselves are exempt from being aspect targets themselves:

Advising aspects with other aspects?

In Spring AOP, it is not possible to have aspects themselves be the target of advice from other aspects. The @Aspect annotation on a class marks it as an aspect, and hence excludes it from auto-proxying.

So M. Prokhorov is somewhat wrong when saying that aspects are not (or cannot be) Spring components, but he is right insofar as by design you cannot self-advise an aspect or advise other aspects. His assumption that it may work with AspectJ is also correct. It does work with AspectJ, so if you need it to you can configure Spring to use AspectJ via LTW instead of Spring AOP for this case.

Upvotes: 1

Related Questions