我在将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工厂将返回相同的实例:您(几乎肯定)每次请求时都需要一个新实例。要做到这一点,只需将其作为“原型”范围即可:请参阅更新后的答案。 –