我有一个带有@Async
注释的服务。从另一个服务调用时,可以在threadExecutor中正确处理它,但如果从带有requestmapping的控制器中调用,则不能正确处理
@Service
public class StartupService implements ApplicationListener<ContextRefreshedEvent> {
private static Logger LOGGER = LoggerFactory.getLogger(StartupService.class);
@Autowired
StockService stockService;
@Override
public void onApplicationEvent(final ContextRefreshedEvent event) {
if(event.getApplicationContext().getParent() == null) {
LOGGER.debug("stockService.load call begin " + Thread.currentThread().getName());
stockService.reload();
LOGGER.debug("stockService.load call end " + Thread.currentThread().getName());
}
}
}
@Controller
@RequestMapping(value = "/api")
public class ApiController {
private static Logger LOGGER = LoggerFactory.getLogger(ApiController.class);
@Autowired
StockService stockService;
@ResponseStatus(value = HttpStatus.OK)
@RequestMapping(value = "/reload.do", method = RequestMethod.GET)
public void reloadStock() {
LOGGER.debug("stockService.load call begin " + Thread.currentThread().getName());
stockService.reload();
LOGGER.debug("stockService.load call end " + Thread.currentThread().getName());
}
}
@Service
public class StockService {
private static Logger LOGGER = LoggerFactory.getLogger(StockService.class);
@Async
public void reload() {
LOGGER.debug("stockService.load run begin " + Thread.currentThread().getName());
//do the magic stuff
LOGGER.debug("stockService.load run end " + Thread.currentThread().getName());
}
}
输出如下。从StockService中的StartupService方法调用时,将在已配置的执行程序中调用。 当从StockService中的ApiController方法调用时,在同一线程中调用
DEBUG [StartupService]: stockService.load call begin http-apr-8080-exec-70
DEBUG [StartupService]: stockService.load call end http-apr-8080-exec-70
DEBUG [StockService]: stockService.load run begin stockexecutor-1
DEBUG [StockService]: stockService.load run end stockexecutor-1
DEBUG [ApiController]: stockService.load call begin http-apr-8080-exec-85
DEBUG [StockService]: stockService.load run begin http-apr-8080-exec-85
DEBUG [StockService]: stockService.load run end http-apr-8080-exec-85
DEBUG [ApiController]: stockService.load call end http-apr-8080-exec-85
答案 0 :(得分:0)
只需重新发布@ M.Deinum的答案即可将其标记为正确答案,因为它对我有很大帮助。
然后,您有2个服务实例,一个实例代理异步,另一个实例不代理。您可能有
ContextLoaderListener
加载了与DispatcherServlet
有效复制bean实例相同的组件
问题是,我在spring-mvc-servlet.xml和applicationContext.xml中使用了组件扫描以查找相同的包