Я пытаюсь запустить асинхронный поток при нажатии кнопки в приложении 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)
Почему это исключение происходит?
И как исправить это исключение?
Почему мои компоненты не автоувеличиваются?
Спасибо.
Бобы не будут автоматически активированы, если ваш класс не инициирован контекстом. Другими словами,
Если ваш класс 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();
...
}
});
}
new Runnable {..}
анонимного объекта new Runnable {..}
. Этот объект также создается не DI, а new
ключевым словом. Я обновлю ответ.
В принципе, вы не должны использовать
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
. Надеюсь, это поможет =)