gpt4 book ai didi

java - Spring JPA 线程 : IllegalArgumentException Exception

转载 作者:行者123 更新时间:2023-11-29 04:58:44 25 4
gpt4 key购买 nike

我已经注释了一个 Thread 类如下:

@Transactional(propagation = Propagation.REQUIRED)
@Component
@Scope("prototype")
public class ThreadRetrieveStockInfoEuronext implements Runnable {
...
}

线程连接到 Controller 类,并通过 Global.poolMultiple.execute(threadRetrieveStockInfoEuronext) 调用;

public class RetrievelController {

@Autowired
private ThreadRetrieveStockInfoEuronext threadRetrieveStockInfoEuronext;

@RequestMapping(value = "/.retrieveStockInfo.htm", method = RequestMethod.POST)
public ModelAndView submitRetrieveStockInfo(@ModelAttribute("retrieveStockInfoCommand") RetrieveStockInfoCommand command, BindingResult result, HttpServletRequest request) throws Exception {

Global.poolMultiple.execute(threadRetrieveStockInfoEuronext);
return new ModelAndView(".retrieveStockInfo", "retrieveStockInfoCommand", command);
}

全局类:

@SuppressWarnings("unchecked")
@Component
public class Global {

// create ExecutorService to manage threads
public static ExecutorService poolMultiple = Executors.newFixedThreadPool(10);
public static ExecutorService poolSingle = Executors.newFixedThreadPool(1);
...
}

运行应用程序时,出现以下异常:

java.lang.IllegalArgumentException: Can not set com.chartinvest.admin.thread.ThreadRetrieveStockInfoEuronext field

com.chartinvest.controller.RetrievelController.threadRetrieveStockInfoEuronext to com.sun.proxy.$Proxy52

最佳答案

那是因为您的 Runnable 实现是一个 Spring 组件,用 @Transactional 注释,并且在 Spring 中,通过将类的实际实例包装在基于 JDK 接口(interface)的代理中来实现声明式事务处理交易。因此, Autowiring 的实际对象不是 ThreadRetrieveStockInfoEuronext 的实例,而是其接口(interface) Runnable 的实例,该接口(interface)委托(delegate)给 ThreadRetrieveStockInfoEuronext 的实例。

通常解决这个问题的方法是 Autowiring 接口(interface)而不是 Autowiring 具体类型。但在这种情况下,这个类首先不应该是 Spring 组件,也不应该是事务性的。顺便说一句,将其设为原型(prototype)会给您一种错觉,即每次调用 submitRetrieveStockInfo() 时都会创建一个新实例,但这是不正确的:创建了一个实例并将其自动连接到 RetrievelController 单例中,因此相同的可运行对象用于所有实例对 Controller 的请求。

只要使 ThreadRetrieveStockInfoEuronext 成为一个简单的类,使用 new 对其进行实例化,将 Spring bean 作为参数传递,并使其 run() 方法调用该 Spring bean 的事务方法:

@Transactional
@Component
public class ThreadRetrieveStockInfoEuronextImpl implements ThreadRetrieveStockInfoEuronext {
@Override
void doSomething() { ... }
}

public class RetrievelController {

@Autowired
private ThreadRetrieveStockInfoEuronext threadRetrieveStockInfoEuronext;

@RequestMapping(value = "/.retrieveStockInfo.htm", method = RequestMethod.POST)
public ModelAndView submitRetrieveStockInfo(@ModelAttribute("retrieveStockInfoCommand") RetrieveStockInfoCommand command, BindingResult result, HttpServletRequest request) throws Exception {

Runnable runnable = new Runnable() {
@Override
public void run() {
threadRetrieveStockInfoEuronext.doSomething();
}
};

Global.poolMultiple.execute(runnable);
return new ModelAndView(".retrieveStockInfo", "retrieveStockInfoCommand", command);
}

关于java - Spring JPA 线程 : IllegalArgumentException Exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32799093/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com