【问题标题】:Is there a Spring AOP annotation which lets us go inside a method only if that annotation returns true? [duplicate]是否有一个 Spring AOP 注释,只有当该注释返回 true 时才允许我们进入一个方法? [复制]
【发布时间】:2018-12-15 10:18:25
【问题描述】:

是否有一个 Spring AOP 注释,只有当该注释返回 true 时才允许我们进入方法内部?

我想要这样的东西:

@CustomAnnotation
public String foo(){
System.out.println("Hello World");
return "foo";
}

所以现在只有当 @CustomAnnotation 返回 true 时,我们才会进入 foo() 方法并打印 Hello World 并返回字符串 "foo" ,但是当 @CustomAnnotation 返回 false 时 - 我们不会进入 foo () 方法。

【问题讨论】:

  • 为什么不自己实现呢?
  • 注解不能返回true或其他任何东西,它不是方法,只是注解。
  • 我的建议是将信息从这个问题移到原始问题,因为这是重复的,我们仍然在这里讨论同样的问题。

标签: java spring annotations spring-aop spring-annotations


【解决方案1】:

要在 spring 中使用 AOP,你应该添加到 pom.xml

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>5.0.1.RELEASE</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.8.12</version>
  <scope>compile</scope>
</dependency>

或者对于 Spring Boot 项目只有一个依赖项

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

要创建自定义注解,我们需要 SkipOnCondition.java

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

我们需要配置我们的切面 EchoAspect.java。为了能够跳过方法,我们选择了Around 拦截点。拦截的触发器将被指定注释。 ProceedingJoinPoint 可以提供有关拦截方法的所有详细信息。例如:参数、签名、...

@Aspect
@Configuration
public class EchoAspect {
    private Logger logger = LoggerFactory.getLogger(EchoAspect.class);

    @Around("@annotation(com.example.demo.aop.SkipOnCondition)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        if ("skip".equals((String) joinPoint.getArgs()[0])){
            logger.info("Condition is true the method will be skipped.");
            return null;
        }
        return joinPoint.proceed();
    }
}

被测对象 Echo.java 有 void 和带有返回类型的方法。

@Component
public class Echo {

    private Logger logger = LoggerFactory.getLogger(Echo.class);

    @SkipOnCondition
    public String echo (String s) {
        return s;
    }

    @SkipOnCondition
    public void blindEcho (String s) {
        logger.info(s);
    }
}

以及概念证明 EchoTest.java

@RunWith(SpringRunner.class)
@SpringBootTest
public class EchoTest {
    private Logger logger = LoggerFactory.getLogger(EchoTest.class);

    @Autowired
    private Echo echo;

    @Test
    public void testEcho() {
        echo.blindEcho("boom");
        echo.blindEcho("skip");
        logger.info(echo.echo("boom"));
        logger.info(echo.echo("skip"));
    }
}

输出将向我们展示它是如何工作的。 echo.blindEcho("boom"); 不满足条件,会按预期执行。 echo.blindEcho("skip"); 将被拦截,因为只会出现特殊的日志消息。 logger.info(echo.echo("boom"));```` doesn't satisfy the condition and will be executed as expected.logger.info(echo.echo("skip"));``` 将被拦截,因为结果会出现特殊的日志消息,并且由于该方法具有返回类型,因此记录器将打印 null。

com.example.demo.aop.Echo                : boom
com.example.demo.aop.EchoAspect          : Condition is true the method will be skipped.
com.example.demo.aop.EchoTest            : boom
com.example.demo.aop.EchoAspect          : Condition is true the method will be skipped.
com.example.demo.aop.EchoTest            : null

更多细节的好例子,link

【讨论】:

  • Uli,很抱歉,在我将这个问题作为重复问题结束之前,您花时间在这里回答。如果这是 OP 想要的,请随意复制(单击“编辑”后)并将此处的内容粘贴到原始问题。如果我为你做,你不会得到作者的认可,所以请你自己做。它不应该花费你超过一两分钟。再次抱歉。
  • @uli,感谢这个例子,但我仍然坚持使用 spring 3 版本,有没有办法在没有 spring boot 并且只有 spring aop 支持的情况下做到这一点? - 我尝试了你上面的代码(除了 pom.xml 更改 - 我们不使用 pom.xml 或 spring boot) - 但它没有成功 - 我认为原因是因为我无法添加 spring boot。一个只使用没有弹簧引导的弹簧 aop 的例子会有所帮助,我也对 Spring 有点了解。谢谢。
  • 你用什么来建项目:maven、gradle、ant?您仍然可以使用我为最初的问题分享的解决方案。
  • IMO 这是一个正确的答案,它也可以在没有 Boot 的 Spring 3 中使用,无论是使用 Spring AOP 还是使用 AspectJ 都会进行较小的配置更改。 Mayank,我认为在某些时候您只需要阅读 Spring 和 Spring AOP 文档并熟悉这些概念。 Uli 不能为您做所有事情,最后一英里您应该独自行走并成为开发人员,而不仅仅是进行复制和粘贴的消费者。无意冒犯。
猜你喜欢
  • 1970-01-01
  • 2011-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多