【问题标题】:Can we enable or disable Aspect based on value of any flag or through configuration file?我们可以根据任何标志的值或通过配置文件启用或禁用 Aspect 吗?
【发布时间】:2015-04-02 06:16:16
【问题描述】:

我在 pom.xml 中添加了以下依赖项

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.5</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.5</version>
        </dependency>

并在appContext.xml中启用AspectJ,如下:

并定义aspect如下:

@Component
@Aspect
public class AuthenticationServiceAspect {


@Before("execution(* com.service.impl.AuthenticationServiceImpl.*(..))")
    public void adviceMethod(JoinPoint joinPoint) {

        if(true){
            throw new Exception();
        }


}

现在我想禁用这个 AOP,这样上面的代码就不会被执行?我该怎么做?

【问题讨论】:

    标签: java aspectj spring-aop


    【解决方案1】:

    您可以使用带有 ConditionalOnExpression 注释的属性的启用/禁用组件。当组件被禁用时,方面也是如此。

    @Component
    @Aspect
    @ConditionalOnExpression("${authentication.service.enabled:true}")// enabled by default
    public class AuthenticationServiceAspect {
        @Before("execution(* com.service.impl.AuthenticationServiceImpl.*(..))")
        public void adviceMethod(JoinPoint joinPoint) {
            if(true){
                throw new Exception();
            }
        }
    }
    

    要禁用方面,只需将 authentication.service.enabled=false 添加到您的 application.properties。

    【讨论】:

    • 感谢这个注释@ConditionalOnExpression 非常适合我的解决方案。
    • 我们如何在 yml 文件中使用配置?
    • 这不适用于 aspectJ 编译时编织...
    【解决方案2】:

    看来 Spring 不支持 AspectJ 的 if() 切入点原语。

    原因:org.springframework.beans.factory.BeanCreationException:创建名为“foo”的bean时出错:bean初始化失败;嵌套异常是 org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException: Pointcut expression 'execution(* doSomething(..)) && if()' contains unsupported pointcut primitive 'if'

    【讨论】:

      【解决方案3】:

      总有 if() 切入点表达式允许您定义要由通知检查的条件: https://www.eclipse.org/aspectj/doc/next/adk15notebook/ataspectj-pcadvice.html#d0e3697

      而且...您的方面已经是 Spring @Component。为什么不直接通过 @Value 注入属性并决定您的建议是否应该执行?您可以通过上述 if() 切入点来执行此操作,或者只需检查通知中的值并因此执行或跳过。

      @Component
      @Aspect
      public class AuthenticationServiceAspect {
      
          @Value("${aspect.active}")
          private boolean active = true;
      
          @Pointcut("execution(* com.service.impl.AuthenticationServiceImpl.*(..)) && if()")
          public static boolean conditionalPointcut() {
              return active;
          }
      
          @Before("conditionalPointcut()")
          public void adviceMethod(JoinPoint joinPoint) {
              if(true){
                  throw new Exception();
              }
          }
      }
      

      【讨论】:

      • 这不起作用,因为active 不是静态的,因此无法从静态方法conditionalPointcut 返回。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-29
      • 1970-01-01
      • 2017-12-23
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      相关资源
      最近更新 更多