@Scheduled 方法内部的 Spring @Async 方法调用

2024-01-04

我正在使用 Spring boot@EnableScheduling and @EnableAsync.

我有一个注释为的方法@Scheduled。 我还有几个方法,注释为@Async.

现在我称这些为@Async中的方法@Scheduled方法并在异步方法中打印出当前线程的名称。我看到的是它们都有相同的线程名称,这实际上是正在运行的线程@Scheduled method.

我没有看到异步方法执行。 这里有什么问题吗?

这是我的应用程序引导类

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class ApplicationBoot {

    public static void main(String[] args) {
        SpringApplication.run(ApplicationBoot.class, args);
    }
}

这是我的调度程序类

@Component
public class TaskScheduler {
    private static final Logger logger = Logger.getLogger(TaskScheduler.class);

    @Scheduled(fixedDelay = 10000)
    public void ScheduledMethod() {
        methodOne();
        methodTwo();
        methodThree();
    }

    @Async
    private void methodOne() {
        logger.info("Method one called  by Thread : " + Thread.currentThread().getName() + "  at " + new Date());
    }

    @Async
    private void methodTwo() {
        logger.info("Method two called  by Thread : " + Thread.currentThread().getName() + "  at " + new Date());
    }

    @Async
    private void methodThree() {
        logger.info("Method three called  by Thread : " + Thread.currentThread().getName() + "  at " + new Date());
    }
}

Output

线程调用的方法一:pool-1-thread-1 at Tue Apr 04 16:32:27 IST 2017

方法二由 Thread 调用:pool-1-thread-1 at Tue Apr 04 16:32:27 IST 2017

方法三由 Thread 调用:pool-1-thread-1 at Tue Apr 04 16:32:27 IST 2017


解释

Spring 在您的实例周围创建一个代理。ScheduledMethod内部调用 3 个方法,这些方法没有被代理,因此不是异步的。

参见文档 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies:

如果您在对象引用上调用方法,则该方法将被调用 直接在该对象引用上,如下所示。

看到这个问题当在 bean 内部调用该方法时,Spring AOP 不起作用 https://stackoverflow.com/questions/30598118/spring-aop-not-working-when-the-method-is-called-internally-within-a-bean一种解决方法,但最好的是文档中提出的方法The best approach (the term best is used loosely here) is to refactor your code such that the self-invocation does not happen...

请注意,私有方法不是也支持 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-pointcuts-designators:

由于 Spring 的 AOP 框架基于代理的性质,受保护的 根据定义,方法不会被拦截,JDK 代理也不会被拦截 (如果这不适用)也不适用于 CGLIB 代理(如果这是 技术上可行,但不推荐用于 AOP 目的)。作为一个 结果,任何给定的切入点都将与公共方法相匹配 仅有的!

解决方法示例

@Component
public class ServiceMethod {
    private static final Logger logger = Logger.getLogger(ServiceMethod .class);

    @Async
    public void methodOne() {
        logger.info("Method one called  by Thread : " + Thread.currentThread().getName() + "  at " + new Date());
    }

    @Async
    public void methodTwo() {
        logger.info("Method two called  by Thread : " + Thread.currentThread().getName() + "  at " + new Date());
    }

    @Async
    public void methodThree() {
        logger.info("Method three called  by Thread : " + Thread.currentThread().getName() + "  at " + new Date());
    }
}

@Component
public class TaskScheduler {
    private static final Logger logger = Logger.getLogger(TaskScheduler.class);

    @Autowired
    private ServiceMethod serviceMethod;

    @Scheduled(fixedDelay = 10000)
    public void ScheduledMethod() {
        serviceMethod.methodOne();
        serviceMethod.methodTwo();
        serviceMethod.methodThree();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

@Scheduled 方法内部的 Spring @Async 方法调用 的相关文章

随机推荐