JavaFX:将Spring框架与JavaFX应用程序集成(配置不正确) [英] JavaFX : Integrating Spring framework with JavaFX app(Incorrect configuration)
问题描述
我正在开发一个JavaFX应用程序,我想集成Spring功能。目前代码编译没有任何错误,但是当我请求服务层方法标记为@Transactional和@Service,我得到NullPointerException。我在Spring配置中做错了什么是我不明白。这是我的JavaFX代码:
主类:
class Main extends Application {
private static final SpringFxmlLoader loader = new SpringFxmlLoader();
@Override
public void start(Stage Stage)throws Exception {
parent root = FXMLLoader.load(getClass()。getClassLoader()。getResource(login.fxml ));
stage.setTitle(APPNAME);
stage.setScene(new Scene(root,300,600));
stage.setFullScreen(false);
stage.setMaximized(false);
stage.show();
}
public static void main(String [] args){
launch(args);
}
}
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {packagename})
public class ApplicationConfiguration {
@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
属性properties = new属性();
propertySourcesPlaceholderConfigurer.setProperties(properties);
return propertySourcesPlaceholderConfigurer;
}
@Bean
public MessageSource messageSource(){
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames(messages,org.springframework.security.messages);
messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
}
SpringLoader:
public class SpringFxmlLoader {
private static final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
public Object load(String url){
try(InputStream fxmlStream = SpringFxmlLoader.class
.getResourceAsStream(url)){
System.err.println(SpringFxmlLoader .class
.getResourceAsStream(url));
FXMLLoader loader = new FXMLLoader();
loader.setControllerFactory(new Callback< Class<?>,Object>(){
@Override
public Object call(Class<?> clazz){
return applicationContext .getBean(clazz);
}
});
return loader.load(fxmlStream);
} catch(IOException ioException){
throw new RuntimeException(ioException);
}
}
}
有这样的:
@Component
public class Controller implements可初始化{
@FXML
public TextField usernameField;
@FXML
public PasswordField passwordField;
@FXML
public Button submitButton;
@Autowired
private PersonService personService;
//现在上面的personService抛出了一个NPE。
}
我不知何故搞错了Spring配置为JavaFX。请让我知道。非常感谢。 : - )
更新
James D..I得到以下错误:
null
应用程序启动方法中的异常
线程mainjava中的异常.lang.RuntimeException:应用程序启动方法中的异常
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda $ launchApplication $ 152(LauncherImpl.java:182)
at com.sun.javafx.application.LauncherImpl $$ Lambda $ 2 / 1058634310.run(未知源)
在java.lang.Thread.run(Thread。 java:745)
原因:java.lang.NullPointerException:inputStream为null。
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2459)
在javafx.fxml.FXMLLoader.load(FXMLLoader.java:2429)
在tooltank.MainClass.SpringFxmlLoader.load (SpringFxmlLoader.java:28)
在tooltank.MainClass.Main.start(Main.java:15)
at com.sun.javafx.application.LauncherImpl.lambda $ launchApplication1 $ 159(LauncherImpl.java: 863)
at com.sun.javafx.application.LauncherImpl $$ Lambda $ 57 / 667705538.run(未知源)
at com.sun.javafx.application.PlatformImpl.lambda $ runAndWait $ 172(PlatformImpl。 java:326)
at com.sun.javafx.application.PlatformImpl $$ Lambda $ 53 / 767743416.run(未知源)
at com.sun.javafx.application.PlatformImpl.lambda $ null $ 170 PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl $$ Lambda $ 55 / 1195477817.run(未知源)
在java.security.AccessController.doPrivileged(本地方法)
at com.sun.javafx.application.PlatformImpl.lambda $ runLater $ 171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl $$ Lambda $ 54 / 1403425489.run(未知来源)
at com.sun.glass.ui.InvokeLaterDispatcher $ Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(本地方法)
at com.sun.glass.ui.gtk.GtkApplication.lambda $ null $ 48(GtkApplication.java:139)
at com.sun.glass.ui.gtk.GtkApplication $$ Lambda $ 43 / 1429486634.run未知来源)
... 1 more
处理完成退出代码1
它发生在SpringFXMLLoader.java中,如下:
return loader.load(fxmlStream);
您已创建一个 SpringFxmlLoader
但您不使用它。你想要
SpringFxmlLoader loader = new SpringFxmlLoader();
parent root =(Parent)loader.load(getClass()。getResource(login.fxml)。toExternalForm());
,而不是直接使用 FXMLLoader
/ p>
我会实际写入 SpringFxmlLoader
,以便它符合标准 FXMLLoader
API有点紧密:
public class SpringFxmlLoader {
private static final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
public< T> T load(URL url){
try {
FXMLLoader loader = new FXMLLoader(url);
loader.setControllerFactory(applicationContext :: getBean);
return loader.load();
} catch(IOException ioException){
throw new RuntimeException(ioException);
}
}
}
:
SpringFxmlLoader loader = new SpringFxmlLoader
parent root = loader.load(getClass()。getResource(login.fxml));
您可能需要修改确切的路径, p>
I am working on a JavaFX application and I would like to integrate Spring functionality with it. Currently the code compiles without any error, but when I request service layer methods which are tagged as @Transactional and @Service, I get NullPointerException. What am I doing wrong in the Spring configuration is what I dont understand. Here is my code for JavaFX :
Main class :
public class Main extends Application {
private static final SpringFxmlLoader loader = new SpringFxmlLoader();
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("login.fxml"));
stage.setTitle("APPNAME");
stage.setScene(new Scene(root, 300, 600));
stage.setFullScreen(false);
stage.setMaximized(false);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"packagename"})
public class ApplicationConfiguration {
@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
Properties properties = new Properties();
propertySourcesPlaceholderConfigurer.setProperties(properties);
return propertySourcesPlaceholderConfigurer;
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages", "org.springframework.security.messages");
messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
}
SpringLoader :
public class SpringFxmlLoader {
private static final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
public Object load(String url) {
try (InputStream fxmlStream = SpringFxmlLoader.class
.getResourceAsStream(url)) {
System.err.println(SpringFxmlLoader.class
.getResourceAsStream(url));
FXMLLoader loader = new FXMLLoader();
loader.setControllerFactory(new Callback<Class<?>, Object>() {
@Override
public Object call(Class<?> clazz) {
return applicationContext.getBean(clazz);
}
});
return loader.load(fxmlStream);
} catch (IOException ioException) {
throw new RuntimeException(ioException);
}
}
}
Now in my Controller, I have something like this :
@Component
public class Controller implements Initializable {
@FXML
public TextField usernameField;
@FXML
public PasswordField passwordField;
@FXML
public Button submitButton;
@Autowired
private PersonService personService;
// Now the above personService throws me a NPE.
}
Am I somehow messing with Spring config for JavaFX. Kindly let me know. Thanks a lot. :-)
Update
After changes suggested by James D..I get the following error :
null
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(LauncherImpl.java:182)
at com.sun.javafx.application.LauncherImpl$$Lambda$2/1058634310.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException: inputStream is null.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2459)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2429)
at tooltank.MainClass.SpringFxmlLoader.load(SpringFxmlLoader.java:28)
at tooltank.MainClass.Main.start(Main.java:15)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
at com.sun.javafx.application.LauncherImpl$$Lambda$57/667705538.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl$$Lambda$53/767743416.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
at com.sun.javafx.application.PlatformImpl$$Lambda$55/1195477817.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
at com.sun.javafx.application.PlatformImpl$$Lambda$54/1403425489.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$48(GtkApplication.java:139)
at com.sun.glass.ui.gtk.GtkApplication$$Lambda$43/1429486634.run(Unknown Source)
... 1 more
Process finished with exit code 1
It happens in SpringFXMLLoader.java at following line :
return loader.load(fxmlStream);
You have created a SpringFxmlLoader
but you are not using it. You want
SpringFxmlLoader loader = new SpringFxmlLoader();
Parent root = (Parent) loader.load(getClass().getResource("login.fxml").toExternalForm());
instead of using the FXMLLoader
directly.
I would actually write the SpringFxmlLoader
differently, so that it matched the standard FXMLLoader
API a little more closely:
public class SpringFxmlLoader {
private static final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
public <T> T load(URL url) {
try {
FXMLLoader loader = new FXMLLoader(url);
loader.setControllerFactory(applicationContext::getBean);
return loader.load();
} catch (IOException ioException) {
throw new RuntimeException(ioException);
}
}
}
Then your start method looks like:
SpringFxmlLoader loader = new SpringFxmlLoader();
Parent root = loader.load(getClass().getResource("login.fxml"));
You might need to tinker with the exact path to get things right, depending on your setup.
这篇关于JavaFX:将Spring框架与JavaFX应用程序集成(配置不正确)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!