簡體   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