Issue
How can we enable/disable an aspect using environment variables?
I know it is possible to enable/disable aspectj in spring boot application using following properties
spring:
aop:
auto: true
Or:
spring.aop.auto=true
And removing @EnableAspectJAutoProxy
, but this stops all of our other aspects / joins.
This is the one I want to disable, how do I do it
@Aspect
@Component
public class SomeAspect {
@Around("@annotation(someAnnotation)")
public Object doSomething(ProceedingJoinPoint joinPoint, SomeAnnotation sa) throws Throwable {
// ...
}
//others
}
Solution
In order to dynamically deactivate a single advice inside an aspect class, you can use an if()
pointcut.
If you want to completely disable an aspect (or any other Spring bean or component) based on conditions like e.g. a property in application.config
, have a look at @Conditional
and its special cases @ConditionalOn*
. For example:
@Aspect
@Component
@ConditionalOnProperty(prefix = "org.acme.myapp", name = "aspect_active")
public class SomeAspect {
// ...
}
Something like this in application.config
would deactivate the aspect:
org.acme.myapp.aspect_active=false
The aspect would also be inactive if there was no such property in the application config at all. If you rather want to default to an active aspect, just use
@ConditionalOnProperty(prefix = "org.acme.myapp", name = "aspect_active", matchIfMissing = true)
You can further fine-tune the behaviour as described in the javadoc.
See also:
- https://www.baeldung.com/spring-conditional-annotations
- https://www.baeldung.com/spring-conditionalonproperty
Update:
In order to dynamically deactivate a single advice inside an aspect class, you can use an
if()
pointcut.
Oops, sorry, I am a native AspectJ user and forgot that Spring AOP does not support the if()
pointcut designator. So probably the best you can do is an if
expression at the beginning of your advice, depending on a @Value
property.
@Value("${org.acme.myapp.advice_active:false}")
private boolean adviceActive;
@Around("@annotation(someAnnotation)")
public Object doSomething(ProceedingJoinPoint joinPoint, SomeAnnotation sa) throws Throwable {
// Skip advice logic if inactive, simply proceed and return original result
if (!adviceActive)
return joinPoint.proceed();
// Regular advice logic if active
System.out.println(joinPoint);
// Either also proceed or do whatever else is the custom advice logic, e.g.
// - manipulate method arguments,
// - manipulate original return value,
// - skip proceeding to the original method altogether and return something else.
return joinPoint.proceed();
}
Of course, you can also use my original solution and just factor out the advice you wish to deactivate into a separate aspect class, if you need that kind of granularity. That would be less hassle, and the advice method code would be more readable.
Answered By - kriegaex