我正在使用Spring 4 Web应用程序,并且遇到同步运行的@Async问题。这是100%注释驱动。没有XML文件。
应用:
package com.kc2112.app;
import com.kc2112.app.controllers.MyStopWatch;
import javax.annotation.Resource;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
@EnableAsync
@EnableScheduling
@Configuration
public class WebApp extends AbstractAnnotationConfigDispatcherServletInitializer implements AsyncConfigurer {
@Resource
@Qualifier("stopwatch")
public MyStopWatch stopwatch;
public WebApp() {
super();
stopwatch = new MyStopWatch();
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[0];
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{AppConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
public TaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor te = new ThreadPoolTaskExecutor();
te.setMaxPoolSize(25);
te.setThreadNamePrefix("LULExecutor-");
te.initialize();
return te;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
配置:
package com.kc2112.app;
import com.kc2112.app.controllers.MySampleService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
@Configuration
@EnableAsync
@ComponentScan( basePackages = {"com"}, excludeFilters={
@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=MySampleService.class)} )
public class AppConfig{
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public UrlBasedViewResolver urlBasedViewResolver()
{
UrlBasedViewResolver res = new InternalResourceViewResolver();
res.setViewClass(JstlView.class);
res.setPrefix("/WEB-INF/jsp/");
res.setSuffix(".jsp");
return res;
}
}
控制器:
package com.kc2112.app.controllers;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyAsyncController {
@Autowired
MyStopWatch stopwatch;
public MySampleService mySampleService = new MySampleService();
@RequestMapping(value = "/go", produces = {MediaType.TEXT_HTML_VALUE}, method = RequestMethod.GET)
public String taskExecutor() throws InterruptedException, ExecutionException {
ArrayList<Future<Boolean>> asyncResults = new ArrayList();
for (int i = 0; i < 10; i++) {
asyncResults.add(mySampleService.callAsync(i));
}
return "time passed is " + stopwatch.getTime();
}
}
Component:
package com.kc2112.app.controllers;
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
@Component
public class MySampleService {
@Async
public Future<Boolean> callAsync(int taskCall) throws InterruptedException {
System.out.println("starting thread" + taskCall);
for (int i = 0; i < 10; i++) {
System.out.println("thread " + taskCall + " count is " + i);
}
return new AsyncResult<Boolean>(true);
}
}
Stopwatch:
package com.kc2112.app.controllers;
import org.apache.commons.lang.time.StopWatch;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Component
@Service
@Qualifier("stopwatch")
public class MyStopWatch extends StopWatch {
public MyStopWatch(){
super();
this.start();
}
}
我尝试了很多东西,但它总是打印显然不是异步的结果。
答案 0 :(得分:0)
public MySampleService mySampleService = new MySampleService();
这是你烦恼的原因。您必须将MySampleService自动装入控制器,而不是自己创建实例。这是Spring将组件包装到异步代理中的唯一方法,该异步代理将检测注释,拦截方法调用,创建任务并将其提交给执行者。
答案 1 :(得分:0)
YES !!!!阅读完这篇文章后:
Spring ThreadPoolTaskExecutor only running one thread
我对我的app类进行了一些更改。关键问题似乎是设置核心池大小。这是修复问题的行的类......
以下是关于它的春季文档:
package com.kc2112.app;
import com.kc2112.app.controllers.MyStopWatch;
import javax.annotation.Resource;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
@EnableAsync
@EnableScheduling
@Configuration
public class WebApp extends AbstractAnnotationConfigDispatcherServletInitializer implements AsyncConfigurer {
@Resource
@Qualifier("stopwatch")
public MyStopWatch stopwatch;
public WebApp() {
super();
stopwatch = new MyStopWatch();
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[0];
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{AppConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
public TaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor te = new ThreadPoolTaskExecutor();
te.setMaxPoolSize(25);
te.setThreadNamePrefix("LULExecutor-");
te.setCorePoolSize(25); //This was the critical line...
te.initialize();
return te;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}