2015-08-20 4 views
1

Я работаю над веб-приложением Spring 4 и столкнулся с проблемой, когда @Async работает синхронно. Это 100% -ная аннотация. Нет файлов XML.Spring 4 Async не работает

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.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(); 
    } 
} 

Я пробовал множество вещей, но он всегда печатает результаты, которые явно не ASync ,

ответ

0
public MySampleService mySampleService = new MySampleService(); 

Это причина ваших проблем. Вы должны авторизовать MySampleService в своем контроллере, а не создавать экземпляр самостоятельно. Это единственный способ для Spring переносить компонент в асинхронный прокси-сервер, который будет обнаруживать аннотацию, перехватывать вызов метода, создавать задачу и отправлять ее исполнителю.

0

ДА !!!! После прочтения этого поста:

Spring ThreadPoolTaskExecutor only running one thread

Я сделал несколько изменений в моем классе приложений. Критическая проблема заключается в том, чтобы установить размер основного пула. Вот класс с линией, что зафиксировало вопрос ...

Вот пружинные документы на него:

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/concurrent/ThreadPoolTaskExecutor.html#setCorePoolSize-int-

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; 
    } 

} 
Смежные вопросы