我正在使用 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(使用前将#替换为@)