@Autowired в ThreadPoolTaskExecutor не работает

1

Я пытаюсь запустить асинхронный поток при нажатии кнопки в приложении 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)

Почему это исключение происходит?

И как исправить это исключение?

Почему мои компоненты не автоувеличиваются?

Спасибо.

  • 0
    В тот момент, когда вы видите «новый» в своем коде, это означает, что фабрика компонентов Spring не работает. Это ваша ответственность тогда.
Теги:
spring-boot
spring
swing

2 ответа

2
Лучший ответ

Бобы не будут автоматически активированы, если ваш класс не инициирован контекстом. Другими словами,

Если ваш класс NewJFrame инициируется вручную new ключевым словом, autowire Framework не сможет autowire переменные свойств внутри этого класса.

Сделайте что-нибудь подобное.

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

И удалите bean-метод mainForm из конфигурационного java файла. И затем переработайте NewJform, как показано ниже. Я не компилировал эту программу. Так что извините меня за любые ошибки компиляции.

Примечание. Ключ должен убедиться, что все @Autowired свойства внутри класса, где он инициировал DI и NOT new. Ваш Runnable также инициируется new ключевым словом, поэтому нам нужно взять myDirectoryReader и authThread из анонимного объекта Runnable.

@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();
              ...
           }
    });
}   
  • 0
    Почему вы говорите об объекте NewJFrame? Это работает очень хорошо. Исключение происходит не при создании экземпляра объекта NewJFrame, а при выполнении Runnable в ThreadPoolTaskExecutor - поле AuthThread authThread; не подключен ...
  • 0
    Вы также должны изменить дизайн new Runnable {..} анонимного объекта new Runnable {..} . Этот объект также создается не DI, а new ключевым словом. Я обновлю ответ.
0

В принципе, вы не должны использовать

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

Во-первых, вы должны понимать, что такое управляемый компонент и неуправляемый компонент. Когда вы используете Spring, все экземпляры ваших классов Java будут созданы и "предварительно загружены" в момент запуска вашего приложения. Другими словами, все классы будут создаваться и управляться весенним контейнером. На практике вы используете @Component (или @Bean, если это делается в классе @Configuration) и @Autowired аннотации.

Когда вы используете "новое" ключевое слово для класса Runnable, то, что вы делаете, нарушает правило наличия пружины для управления всеми вашими компонентами (или классами). Теперь "new Runnable(){}" больше не управляется весной, но вы ожидаете, что Spring добавит все классы @Autowired в ваш класс Runnable. Все @Autowired объекты в new Runnable(){} уже недоступны весной.

Вы можете обратиться к этой ссылке, чтобы узнать, как mkyong использует ThreadPoolTaskExecutor. Обратите внимание на ту часть, которую он назвал классом PrintTask implements Runnable. Надеюсь, это поможет =)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню