Spring @Async가 작동하지 않음
안 안@Async
에 있는 .@Service
되지 않습니다 -http://timeout . -http://timeout class는 스레드를 . 스레드를 차단하고 있습니다.
가지고 있습니다<task: annotation-driven />
내 구성에서는 메소드에 대한 호출이 클래스 외부에서 오고 있으므로 프록시가 타격을 받아야 합니다.코드를 통과하면 프록시가 실제로 작동하지만 태스크 실행자에서 실행하는 것과 관련된 클래스 근처에는 가지 않는 것 같습니다.
브레이크 포인트를 넣었습니다.AsyncExecutionInterceptor
절대 안 맞아요로 디버그했습니다.AsyncAnnotationBeanPostProcessor
그리고 조언이 적용되는 것을 볼 수 있습니다.
됩니다.@Async
에 주석을 .@Async
역시. 둘 다 표시되어 있지 않습니다.@Transactional
.
뭐가 잘못됐는지 짐작 가는 게 있나요?
-=UPDATE=-
흥미롭게도, 그것은 내가 가지고 있을 때만 작동합니다.task
XML 요소는 내 app-servlet.xml 파일에 있고, 내 app-services.xml 파일에는 없으며, 거기서 서비스에 대한 구성 요소 검색도 수행하면 됩니다.일반적으로 하나의 XML 파일에 컨트롤러만 포함되어 있고(그에 따라 구성 요소 검색을 제한함), 다른 하나의 XML 파일에 서비스가 포함되어 있습니다(다른 파일에 로드된 컨트롤러를 다시 검색하지 않도록 구성 요소 검색이 제한됨).
app-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:webflow="http://www.springframework.org/schema/webflow-config"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"
>
<task:annotation-driven executor="executor" />
<task:executor id="executor" pool-size="7"/>
<!-- Enable controller annotations -->
<context:component-scan base-package="com.package.store">
<!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> -->
</context:component-scan>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
app-services.xml(여기에 지정하면 작동하지 않음)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<!-- Set up Spring to scan through various packages to find annotated classes -->
<context:component-scan base-package="com.package.store">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<task:annotation-driven executor="han" />
<task:executor id="han" pool-size="6"/>
...
구성에 명백한 내용이 누락되었거나 구성 요소 간에 미묘한 상호 작용이 이루어지고 있습니까?
나에게 해결책은 추가하는 것이었습니다.@EnableAsync
돈으로@Configuration
주석이 달린 클래스:
@Configuration
@ComponentScan("bla.package")
@EnableAsync
public class BlaConfiguration {
}
패키지의 입니다.bla.package
이 있는@Async
주석이 달린 메소드는 실제로 비동기식으로 호출될 수 있습니다.
Ryan Stewart의 이 훌륭한 답변의 도움으로, 저는 (적어도 제 특정 문제에 대해서는) 이것을 알아낼 수 있었습니다.
말해서, 간히말해서, 트가로니다드됩에 입니다.ContextLoaderListener
는 ("applicationContext.xml")에 입니다.DispatcherServlet
으로부터) )*-servlet.xml
콩을 먹을 수 있습니다.@Async
컨텍스트의 (method declarated/component-context, component-context)DispatcherServlet
컨텍스트에 합니다.ContextLoaderListener
하였습니다.*-servlet.xml
이제 예상대로 작동합니다.
Jiři Vypědřik의 대답은 제 문제를 해결했습니다.구체적으로.
- @Async로 주석을 단 메서드가 public인지 확인합니다.
Spring 튜토리얼 https://spring.io/guides/gs/async-method/ 의 다른 유용한 정보:
Facebook의 로컬 인스턴스 만들기LookupService 클래스에서 findPage 메서드를 비동기적으로 실행할 수 없습니다.@Configuration 클래스 내에 만들거나 @ComponentScan에서 선택해야 합니다.
이것이 의미하는 바는, 만약 당신이 정적인 방법을 가지고 있다면, Foo.bar 는 그것을 그런 식으로 호출할 수 없다는 것입니다. 비록 그것이 @Async로 주석이 달렸더라도, 비동기식으로 실행하지 않을 것입니다.@Component로 Foo에 주석을 달아야 하며 호출 클래스에서 Foo의 @Autowired 인스턴스를 가져옵니다.
즉, 클래스 Foo에 주석이 달린 메서드 표시줄이 있는 경우:
@Component
class Foo {
@Async
public static void bar(){ /* ... */ }
@Async
public void bar2(){ /* ... */ }
}
호출자 클래스의 A:
class Test {
@Autowired Foo foo;
public test(){
Foo.bar(); // Not async
foo.bar(); // Not async
foo.bar2(); // Async
}
}
편집: 정적으로 호출하는 것처럼 보이지만 비동기로 실행하지 않습니다.
이게 도움이 되길 바랍니다.
- 추가시를 추가해 .
proxy-target-class="true"
누구에게나<*:annotation-driven/>
이 속성을 지원하는 요소. - 에 방에주달렸확인다니합지는으로 하세요.
@Async
공개합니다.
나의 경우에는@Async
메서드가 이 메서드를 사용한 동기화 메서드와 동일한 클래스에 정의되었으며, 이로 인해 모든 작업이 현재 스레드에서 중단되었습니다.
나빠
@Component
@EnableAsync
public class TranslationGapiReader {
@Async
public CompletableFuture<GapiFile> readFile(String fileId) {
try { Thread.sleep(2000); } catch (Exception exc) { throw new RuntimeException("ololo", exc); }
return CompletableFuture.completedFuture(null);
}
public Stream<GapiFile> readFiles(Iterable<String> fileIds) {
List<CompletableFuture<GapiFile>> futures = new ArrayList<>();
for (String fileId: fileIds) {
futures.add(readFile(fileId));
}
return Stream.empty();
}
}
좋아요.
@Component
@EnableAsync
public class AsyncGapiFileReader {
@Async
public CompletableFuture<TranslationGapiReader.GapiFile> readFile(String fileId) {
try { Thread.sleep(2000); } catch (Exception exc) { throw new RuntimeException("ololo", exc); }
return CompletableFuture.completedFuture(null);
}
}
@Component
@EnableAsync
public class TranslationGapiReader {
@Autowired
AsyncGapiFileReader asyncGapiFileReader;
public Stream<GapiFile> readFiles(Iterable<String> fileIds) {
List<CompletableFuture<GapiFile>> futures = new ArrayList<>();
for (String fileId: fileIds) {
futures.add(asyncGapiFileReader.readFile(fileId));
}
return Stream.empty();
}
}
나는 스프링 구루가 아니다 왜 그것이 오직 그것이 작동하는지 이해할 만큼.@Async
방법은 다른 클래스에 있지만, 그것이 내 관찰에서 문제를 해결하는 것입니다.
먼저 당신의 것을 만듭니다..xml
구성은 다음과 같습니다.
<task:scheduler id="myScheduler" pool-size="10" />
<task:executor id="myExecutor" pool-size="10" />
<task:annotation-driven executor="myExecutor" scheduler="myScheduler" proxy-target-class="true" />
(예, 스케줄러 수 및 실행자 스레드 풀 크기를 구성할 수 있습니다.
또는 기본값을 사용합니다.
<!-- enable task annotation to support @Async, @Scheduled, ... -->
<task:annotation-driven />
두 번째로 확인합니다.@Async
메서드는 공개됩니다.
@Async는 @PostConstruct와 같은 수명 주기 콜백과 함께 사용할 수 없습니다.Spring bean을 동시에 초기화하려면 현재 대상에서 @Async 주석이 달린 메서드를 호출하는 별도의 초기화 Spring bean을 사용해야 합니다.
public class SampleBeanImpl implements SampleBean {
@Async
void doSomething() { … }
}
public class SampleBeanInititalizer {
private final SampleBean bean;
public SampleBeanInitializer(SampleBean bean) {
this.bean = bean;
}
@PostConstruct
public void initialize() {
bean.doSomething();
}
}
저는 튜토리얼 비동기 방식 튜토리얼 코드에 따라 제 이슈 소스가 주석이 달린 콩이라는 것을 깨달았습니다.@Async
메서드가 프록시로 감싸여 생성되지 않았습니다.땅을 파기 시작했고 깨달았어요. "이 세상에서 가장 중요한 것은
빈의 이름Bean'은 일부 BeanPostProcessor에서 처리할 수 없습니다(예: 자동 프록시 사용 불가).
이 문제에 대한 반응을 보실 수 있습니다. 기본적으로 Bean Post Processor는 모든 Bean에 의해 필요합니다. 따라서 여기에 주입된 모든 Bean과 그 의존성은 나중에 다른 Bean Post Processor에 의해 처리되는 것이 제외됩니다. 왜냐하면 이것은 Bean의 수명 주기를 손상시켰기 때문입니다.따라서 다음 중 어느 것인지 식별합니다.BeanPostProcessor
그것은 이것을 유발하고 그 안에 콩을 사용하거나 만들지 않습니다.
제 경우에는 이 구성이 있었습니다.
@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
@Autowired
private Wss4jSecurityInterceptor securityInterceptor;
@Autowired
private DefaultPayloadLoggingInterceptor payloadLoggingInterceptor;
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(securityInterceptor);
interceptors.add(payloadLoggingInterceptor);
}
}
WsConfigurerAdapter
은 사은실입니다.BeanPostProcessor
항상 이 있기 : 항상패턴있때깨됩닫니게다에문기이:됩▁and다니▁there.@Configuration
클래스를 확장하고 일부 기능을 재정의하여 웹 서비스 또는 보안과 같은 일부 비기능 기능에 관련된 빈을 설치하거나 조정합니다.
위의 예에서 당신은 다음을 무시해야 합니다.addInterceptors
에 그고인콩추을가다니했 같은 한다면. 그래서 만약 당신이 다음과 같은 주석을 사용한다면.@Async
東京의 DefaultPayloadLoggingInterceptor
작동하지 않을 것입니다.해결책은 무엇일까?없애버려요WsConfigurerAdapter
시작하기 위해. 난 는 금조파난후저이는붙름깨수다니습달라는 .PayloadRootAnnotationMethodEndpointMapping
마지막에는 모든 유효한 인터셉트가 있는 것이었기 때문에 함수를 재정의하는 대신 수동으로 했습니다.
@EnableWs
@Configuration
public class WebServiceConfig {
@Autowired
private Wss4jSecurityInterceptor securityInterceptor;
@Autowired
private DefaultPayloadLoggingInterceptor payloadLoggingInterceptor;
@Autowired
public void setupInterceptors(PayloadRootAnnotationMethodEndpointMapping endpointMapping) {
EndpointInterceptor[] interceptors = {
securityInterceptor,
payloadLoggingInterceptor
};
endpointMapping.setInterceptors(interceptors);
}
}
그래서 결국 이것은 실행될 것입니다.BeanPostProcessor
그들의 임무를 완수했습니다.setupInterceptors
함수는 파티가 끝나면 실행되고 인터셉트 빈을 설치합니다.이 사용 사례는 보안과 같은 사례로 추정할 수 있습니다.
결론:
- 이를 에는 @Configuration @Configuration ▁of▁a▁inside▁that▁if▁probably▁automatic▁are▁extending▁youconfiguration다니있▁@▁from습▁class▁themconfig수▁a일▁you부▁runs▁you▁functions▁some할수▁some▁using▁given▁are행,을uration▁override지정을업작ally된
BeanPostProcessor
그러므로 거기에 콩을 주입하지 말고 AOP 동작을 사용하려고 노력하면 작동하지 않을 것이기 때문에, 당신은 콘솔에서 앞서 언급한 메시지와 함께 봄이 당신에게 알려주는 것을 보게 될 것입니다. 물건을합니다.new
조항). - 을 어떤 , 막에설콩정어클을가떤래가있대면한콩파다야을해에는지지마고할지스▁if▁is,▁dig▁youg한다면파▁beans▁class▁at▁the야▁about▁which▁you콩을▁carrying,▁end▁beans대.
@Autowired
전에 했던 것처럼 그 콩들을 첨가하세요.
이것으로 시간을 절약할 수 있기를 바랍니다.
비동기가 작동하려면 코드 3줄이 필요합니다.
- applicationContext.xml에서
- 클래스 레벨에서 @EnableAsync
- @Async 방법 수준
@Service @Async public myClass {} 사용
@Async public void myMethod(){
}
비동기 bean에 대한 독립적인 Spring 구성을 작성합니다.
예:
@Configuration
@ComponentScan(basePackages="xxxxxxxxxxxxxxxxxxxxx")
@EnableAsync
public class AsyncConfig {
/**
* used by asynchronous event listener.
* @return
*/
@Bean(name = "asynchronousListenerExecutor")
public Executor createAsynchronousListenerExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(100);
executor.initialize();
return executor;
}
}
저는 이 상황으로 이 문제를 극복합니다.
아래에서 시도: 1.에서 "용 콩"을합니다.ThreadPoolTaskExecutor
@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
return new ThreadPoolTaskExecutor();
}
@Async가 사용되는 서비스 메서드에서 추가
@Async("threadPoolTaskExecutor")
public void asyncMethod(){
//do something
}
@Async가 작동합니다.
언급URL : https://stackoverflow.com/questions/6610563/spring-async-not-working
'programing' 카테고리의 다른 글
스토리보드에 사용자 지정 글꼴이 있는 속성 문자열이 올바르게 로드되지 않음 (0) | 2023.08.20 |
---|---|
Excel에서 사용자 정의 문서 속성에 문서 속성을 추가하는 방법은 무엇입니까? (0) | 2023.08.20 |
워크북의 시트 수를 아는 방법은 무엇입니까? (0) | 2023.08.20 |
Chrome 디버거가 닫힌 로컬 변수가 정의되지 않았다고 생각하는 이유는 무엇입니까? (0) | 2023.08.15 |
TWIG 템플릿에서 세션 액세스 (0) | 2023.08.15 |