ThreadPoolTaskExecutor 中的@Autowired不起作用



我试图在Java GUI应用程序中按按钮运行异步线程。

我的代码是:

配置类别:

@Configuration
@ComponentScan({"khartn", "khartn.torrentsuploader.processor"})
public class AppConfig {
@Bean(initMethod = "init")
public NewJFrame mainForm() {
System.out.println("init mainForm");
return new NewJFrame();
}
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(5);
pool.setMaxPoolSize(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
pool.initialize();
return pool;
}
}

JFrame类:

public class NewJFrame extends javax.swing.JFrame {
@Autowired
FileProcessor fileProcessor;
@Autowired
ThreadPoolTaskExecutor taskExecutor;
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
taskExecutor.execute(new Runnable() {
@Autowired
MyDirectoryReader myDirectoryReader;
@Autowired
AuthThread authThread;
@Override
public void run() {
jLabel3.setText("Авторизация...");
Boolean authSuccessfull = false;
while (!authSuccessfull) {
authSuccessfull = authThread.auth();
}
jLabel3.setText("Загрузка файлов");
myDirectoryReader.readDir();
}
});
}   

我在线上出错

authSuccessfull = authThread.auth();

java.lang.NullPointerException
at khartn.torrentsuploader.form.NewJFrame$4.run(NewJFrame.java:162)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

为什么会出现此异常?

如何修复此异常?

为什么我的组件没有自动连接?

谢谢。

如果您的类不是由上下文启动的,那么Beans将不会自动连接。换句话说,

如果您的类NewJFrame是由new关键字手动启动的,则spring框架将无法autowire该类内的属性变量。

做这样的事。

@Component("mainForm")
public class NewJFrame extends javax.swing.JFrame {

并从配置java文件中删除bean方法mainForm。然后重新设计NewJform,如下所示。我没有编译这个程序。请原谅我的任何编译错误。

注意:关键是要确保类中的所有@Autowired属性都由DI启动,并且NOTnew启动。Runnable也是由new关键字初始化的,这就是为什么我们需要从匿名Runnable对象中取出myDirectoryReaderauthThread

@Component("mainForm")
public class NewJFrame extends javax.swing.JFrame {
@Autowired
FileProcessor fileProcessor;
@Autowired
ThreadPoolTaskExecutor taskExecutor;
@Autowired
MyDirectoryReader myDirectoryReader;
@Autowired
AuthThread authThread;

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
taskExecutor.execute(new Runnable() {
@Override
public void run() {
...
authSuccessfull = authThread.auth();
...
}
});
}   

基本上,您不应该使用

taskExecutor.execute(new Runnable(){
// do something here
});

首先,您必须了解什么是托管Bean和非托管Bean。当您使用Spring时,java类的所有实例都将在启动应用程序时被实例化并"预加载"。换句话说,所有类都将由spring容器实例化和管理。在实践中,您可以使用@Component(如果在@Configuration类中完成,则可以使用@Bean)和@Autowired注释。

当您为类Runnable使用"new"关键字时,您所做的就是打破让spring管理所有bean(或类)的规则。现在"new Runnable(){}"不再由spring管理,但您希望spring在Runnable类中注入所有的@Autowired类。new Runnable(){}中的所有@Autowired对象都已从spring中脱离。

您可以参考此链接来了解mkyong是如何使用ThreadPoolTaskExecutor的。请注意他将类命名为PrintTask implements Runnable的部分。希望这有帮助=)

最新更新