我使用@EnableScheduling
和@EnableAsync
进行Spring启动。
我有一个用@Scheduled
注释的方法。
我还有一些方法,用@Async
注释。
现在我在@Async
方法中调用这些@Scheduled
方法,并在异步方法中打印出当前线程的名称。我看到的是它们都有相同的线程名称,实际上它是运行@Scheduled
方法的线程。
我没有看到异步方法执行。 这有什么不对?
这是我的应用程序启动类
@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());
}
}
输出
方法一由Thread调用:pool-1-thread-1在Tue Apr 04 16:32:27 IST 2017
方法二由Thread调用:pool-1-thread-1在Tue Apr 04 16:32:27 IST 2017
方法三由Thread调用:pool-1-thread-1在Tue Apr 04 16:32:27 IST 2017
答案 0 :(得分:11)
<强>解释强>
Spring在您的实例周围创建代理。 ScheduledMethod
内部调用3个方法,这些方法未被代理,因此不是异步的。
如果在对象引用上调用方法,则调用该方法 直接在该对象引用上,如下所示。
请参阅此问题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...
请注意,私有方法不是supported too:
由于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();
}
}
答案 1 :(得分:4)