繁体   English   中英

如何在springboot中使用@Async和@Scheduled注释?

[英]How to use @Async with @Scheduled annotation in springboot?

我想使用@scheduled和@Async注释,但是当我启动服务器时,我得到了这个异常,如果我删除@Async注释,它可以正常工作。 任何帮助,将不胜感激。

@Component
public class NService  {

@Scheduled(fixedDelay =70*100)
@Async
public void someMethod() throws SQLException {

    //some Processing
}
}

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.IllegalStateException: Need to invoke method 'recordHeartBeat' declared on target class 'NodeStatusService', but not found in any interface(s) of the exposed proxy type. Either pull the method up to an interface or switch to CGLIB proxies by enforcing proxy-target-class mode in your configuration.
at org.springframework.core.MethodIntrospector.selectInvocableMethod(MethodIntrospector.java:135)
at org.springframework.aop.support.AopUtils.selectInvocableMethod(AopUtils.java:130)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:341)
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:324)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:423)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1633)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
... 20 common frames omitted

该错误提供了建议:

方法'recordHeartBeat'在目标类'NodeStatusService'上声明,但在公开的代理类型的任何接口中都找不到。 通过在配置中强制执行proxy-target-class模式,将方法提升到接口或切换到CGLIB代理。

要正常运行,@ Async注释需要为您的类创建代理(包装器)。 执行顺序为:

来电 - >代理方法 - >您的类方法

Spring可以使用两种方式自动创建代理:

1)通过实现接口

如果一个类实现了一个接口,Spring可以创建一个代理类来实现该接口并将其注入执行路径。 这是错误消息中建议的第一部分:

将方法拉到界面

要按照这种方式,您需要使用public void recordHeartBeat() throws SQLException创建一个接口public void recordHeartBeat() throws SQLException并在类中实现您的接口,例如:

public interface HeartBeater {
  void recordHeartBeat() throws SQLException;
}

public class NodeStatusService implements NodeStatus implements HeartBeater {
....
}

2)通过使用CGLIB创建字节码代理

如果一个类没有实现使用@Async注释声明方法的接口,那么Spring可以使用CGLIB创建一个字节码代理。 它使用字节码操作来改变调用序列。

这是错误消息中建议的第二部分:

通过在配置中强制执行proxy-target-class模式切换到CGLIB代理

您可以通过向配置bean添加注释来启用代理目标类:

@EnableAspectJAutoProxy(proxyTargetClass = true)

请参阅文档以获取示例: https//docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/EnableAspectJAutoProxy.html

根据错误堆栈,它表示将方法recordHeartBeat()移动到NodeStatus接口或使用CGLib proxy

Caused by: java.lang.IllegalStateException: Need to invoke method 'recordHeartBeat' declared on target class 'NodeStatusService', but not found in any interface(s) of the exposed proxy type. Either pull the method up to an interface or switch to CGLIB proxies by enforcing proxy-target-class mode in your configuration. 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM