Java 注释不适用于 Callable

标签 java annotations aspectj

我编写了一个注释(在Spring Boot应用程序中)并尝试将其应用到Callablecall()方法上,但它不起作用,但另一方面,当应用于普通方法时(请参阅下面的代码),它有效,这一直困扰着我,你能给我一些线索吗?非常感谢。

这是我的代码,

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

@Aspect
@Component
public class LogExecutionTimeAspect {

    private static final Logger logger = LoggerFactory.getLogger(LogExecutionTimeAspect.class);

    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        final long start = System.currentTimeMillis();
        final Object proceed = joinPoint.proceed();
        final long executionTime = System.currentTimeMillis() - start;
        logger.info(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        return proceed;
    }
}


public class DummyCallable implements Callable<Integer> {

    private Integer start, count;

    DummyCallable() {}

    DummyCallable(Integer start, Integer count) {
        this.start = start;
        this.count = count;
    }

    @LogExecutionTime // not working...
    @Override
    public Integer call() throws Exception {
        Thread.sleep(start * 1000);
        Integer sum = 0;
        for (Integer i = start; i <= start + count; i++) {
            sum += i;
        }
        return sum;
    }
}



@LogExecutionTime // This will work... 
public List<Integer> getAllUserScores() {
    Callable c1 = new DummyCallable(1, 100000);
    Callable c2 = new DummyCallable(2, 100000);
    Callable c3 = new DummyCallable(3, 100000);
    // .... run them ...
    return result;
}

最佳答案

受到@sbjavateam的启发,我意识到三件事,

  1. spring aop 仅适用于由 spring 容器管理的对象。要为您的类应用切面,它应该是一个 bean 或组件,并由 spring 上下文实例化。(好吧,这是从 @sbjavateam 的答案复制的。)
  2. 基于前一个语句,Callable c1 = new DummyCallable(1, 100000);本质上是错误的,因为我们必须从 spring 上下文创建 DummyCallable (以便 bean 能够正确注入(inject)其依赖项),无法调用 new
  3. DummyCallable 类需要具有原型(prototype)范围,以便它不是单例。单例范围是 Spring bean 的默认范围。因此,此类必须具有以下注释:@Scope("prototype")

下面是我的修复,

@Component
@Scope("prototype")
public class DummyCallable implements Callable<Integer> {}


private DummyCallable createDummyCallable(Integer start, Integer end) {
        return context.getBean(DummyCallable.class, start, end);
    }

此外,您可能也需要此配置,

spring.aop.proxy-target-class=true

最后但并非最不重要的一点,非常感谢你,@sbjavateam。

关于Java 注释不适用于 Callable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44864658/

相关文章:

java - 递归计算前 k 个序列的和 1 + (1/2)-(1/3)+(1/4)......(1/k)

java - 带点的属性名称 Jackson JSON 解析

java - 如何使用 aspectJ 快速修改已编译的 java 类行为

java - AspectJ:跟踪新对象初始化

java - 使用 JDBC 连接到不同数据库的模式

java - 抑制错误消息 找不到要查询的实体

java - Gradle 构建未完成

java - 注释中数组的安全性

eclipse - 删除文本编辑器注释类型

java - Spring:标准日志方面(拦截器)