繁体   English   中英

ThreadPoolTask​​Executor中的@Autowired不起作用

[英]@Autowired in ThreadPoolTaskExecutor doesn't work

我试图在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)

为什么会发生此异常?

以及如何解决此异常?

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

谢谢。

如果您的类不是由上下文启动的,则Bean将不会自动装配。 换一种说法,

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

做这样的事情。

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

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

注意:关键是确保类中的所有@Autowired属性由DI不是 new发起。 您的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,则可以使用@Bean)和@Autowired注释。

当为类Runnable使用“ new”关键字时,您正在做的事情是打破使用spring管理所有bean(或类)的规则。 现在, "new Runnable(){}"不再由spring管理,但是您希望spring将所有@Autowired类注入到Runnable类中。 从春季起, new Runnable(){}中的所有@Autowired对象都已无法使用。

您可以参考此链接以查看mkyong如何使用ThreadPoolTask​​Executor。 在他将类命名为PrintTask implements Runnable那部分要注意PrintTask implements Runnable 希望这可以帮助=)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM