我在將JavaFX和Spring結合時遇到問題。我有簡單的JavaFX應用程序,它工作正常。現在我正在嘗試添加一些Spring。我跟着JavaFX 2 with Spring Tutorial。我的代碼:JavaFX和Spring - bean不Autofire
src/main
|
|_java/mycompany/imageviewer
| |
| |_Startup.java
| |_controller/ImageViewController.java
| |_dataprovider
| |impl/DataProviderImpl.java
| |_config
| |_SpringFxmlLoader.java
| |_SpringApplicationConfig.java
|_resources/mycompany/view/ImageViewer.fxml
Startup.java
是文件與主:
public class Startup extends Application {
private static final SpringFxmlLoader loader = new SpringFxmlLoader();
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
...
Parent root = (Parent) loader.load("/mycompany/imageviewer/view/ImageViewer.fxml","mycompany/imageviewer/bundle/bundle");
Scene scene = new Scene(root);
...css etc...
primaryStage.setScene(scene);
primaryStage.show();
}
}
ImageviewerController.java
:
@Controller
public class ImageViewerController {
private static final Logger LOG = Logger.getLogger(ImageViewerController.class);
@FXML
...
@Autowired
private DataProvider dataProvider;
public ImageViewerController() {
LOG.debug("Controller initialized. DataProvider is null: "+(dataProvider==null));
}
DataProviderImpl.java
:
@Service("dataProvider")
public class DataProviderImpl implements DataProvider {
private static final Logger LOG = Logger.getLogger(DataProviderImpl.class);
public DataProviderImpl() {
LOG.debug("DataProviderImpl initialized.");
}
...methods...
}
我SpringFxmlLoader看起來教程與此類似:
public class SpringFxmlLoader {
private static final ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringApplicationConfig.class);
public Object load(String url, String resources) {
FXMLLoader loader = new FXMLLoader();
loader.setControllerFactory(clazz -> applicationContext.getBean(clazz));
try {
return loader.load(getClass().getResource(url), ResourceBundle.getBundle(resources));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
我SpringApplicationConfig:
@Configuration
@ComponentScan(basePackages = {"mycompany.imageviewer.controller", "mycompany.imageviewer.dataprovider.impl" })
public class SpringApplicationConfig {
private static final Logger LOG = Logger.getLogger(SpringApplicationConfig.class);
@Bean
public DataProvider dataProvider() {
LOG.debug("Initializing dataProvider via SpringApplicationConfig");
return new DataProviderImpl();
}
@Bean
public ImageViewerController imageViewerController() {
LOG.debug("Initializing ImageViewerController via SpringApplicationConfig");
return new ImageViewerController();
}
}
在我的應用我有ImageViewer.fxml
與綁定控制器:
<AnchorPane fx:controller="mycompany.imageviewer.controller.ImageViewerController" xmlns="http://javafx.com/javafx/8.0.51" xmlns:fx="http://javafx.com/fxml/1" >
當我運行程序,我得到的日誌:
DEBUG [main] mycompany.imageviewer.controller.ImageViewerController:74 - Controller initialized. DataProviderImpl is null: true
DEBUG [main] mycompany.imageviewer.dataprovider.impl.DataProviderImpl:22 - DataProviderImpl initialized.
DEBUG [JavaFX Application Thread] mycompany.imageviewer.controller.ImageViewerController:74 - Controller initialized. DataProviderImpl is null: true
其中顯示我的控制器已初始化兩次,並且dataProvider
未正確綁定。是什麼讓我困惑,是我在ComponentScan
以這種方式與錯包不期而遇寫錯basePackages
:
@ComponentScan(basePackages = {"mycompany.imageviewer.dataprovider.controller", "mycompany.imageviewer.dataprovider.dataprovider.impl" })
豆初始化SpringApplicationConfig.java
運行的方法,我也得到原木他們:
2015-09-06 16:52:29,420 DEBUG [main] com.capgemini.starterkit.imageviewer.config.SpringApplicationConfig:19 - Initializing dataProvider via SpringApplicationConfig
2015-09-06 16:52:29,431 DEBUG [main] com.capgemini.starterkit.imageviewer.dataprovider.impl.DataProviderImpl:22 - DataProviderImpl initialized.
DEBUG [main] mycompany.imageviewer.config.SpringApplicationConfig:25 - Initializing ImageViewerController via SpringApplicationConfig
DEBUG [main] mycompany.imageviewer.controller.ImageViewerController:74 - Controller initialized. DataProviderImpl is null: true
DEBUG [JavaFX Application Thread] mycompany.imageviewer.controller.ImageViewerController:74 - Controller initialized. DataProviderImpl is null: true
當我運行basePackages = "com.capgemini.starterkit.imageviewer"
的效果與第一種情況相同。 我是新來的春天,可能我犯了一些簡單的錯誤,但我無法找到它們,所以如果有人可以幫我配置春天,那將是很棒的。:-)
非常感謝你,你的回答解決了我的問題。但我不得不承認,我不理解你的最後一段,但我明白,我不應該使用我的'ImageViewerController'作爲bean。你能解釋一下這個問題有什麼好的解決方法嗎? –
我不是說你不應該把它當作bean來使用,只是你不應該讓它具有singleton範圍。 Singleton作用域意味着每當請求時,bean工廠將返回相同的實例:您(幾乎肯定)每次請求時都需要一個新實例。要做到這一點,只需將其作爲「原型」範圍即可:請參閱更新後的答案。 –