From 441fae4d5391d629abae2e6be05ff86994a6ebc7 Mon Sep 17 00:00:00 2001 From: lhanda <62590149+lhanda@users.noreply.github.com> Date: Tue, 27 Jul 2021 18:34:47 +0800 Subject: [PATCH] feat: autoscan and initialize fxmlview annotated beans Autoscan basepackages specified in 'fxweaver.autoscan.basepackages' property in application.properties for fxmlview annotated beans and auto initialized them. --- .../starter/controller/MainWindow.java | 13 +++---- .../starter/controller/SomeDialog.java | 14 ++++---- .../src/main/resources/application.properties | 2 ++ .../FxWeaverAutoConfiguration.java | 35 +++++++++++++++++-- 4 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 samples/springboot-starter-sample/src/main/resources/application.properties diff --git a/samples/springboot-starter-sample/src/main/java/net/rgielen/fxweaver/samples/springboot/starter/controller/MainWindow.java b/samples/springboot-starter-sample/src/main/java/net/rgielen/fxweaver/samples/springboot/starter/controller/MainWindow.java index c1546d7..1a085a5 100644 --- a/samples/springboot-starter-sample/src/main/java/net/rgielen/fxweaver/samples/springboot/starter/controller/MainWindow.java +++ b/samples/springboot-starter-sample/src/main/java/net/rgielen/fxweaver/samples/springboot/starter/controller/MainWindow.java @@ -2,28 +2,25 @@ import javafx.fxml.FXML; import javafx.scene.control.Button; -import javafx.scene.layout.VBox; -import net.rgielen.fxweaver.core.FxControllerAndView; import net.rgielen.fxweaver.core.FxmlView; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component @FxmlView public class MainWindow { - private final FxControllerAndView someDialog; + @Autowired + private SomeDialog someDialog; @FXML public Button openDialogButton; - public MainWindow(FxControllerAndView someDialog) { - this.someDialog = someDialog; - } - @FXML public void initialize() { openDialogButton.setOnAction( - actionEvent -> someDialog.getController().show() + actionEvent -> this.someDialog.show() ); } diff --git a/samples/springboot-starter-sample/src/main/java/net/rgielen/fxweaver/samples/springboot/starter/controller/SomeDialog.java b/samples/springboot-starter-sample/src/main/java/net/rgielen/fxweaver/samples/springboot/starter/controller/SomeDialog.java index a009c04..bb50df5 100644 --- a/samples/springboot-starter-sample/src/main/java/net/rgielen/fxweaver/samples/springboot/starter/controller/SomeDialog.java +++ b/samples/springboot-starter-sample/src/main/java/net/rgielen/fxweaver/samples/springboot/starter/controller/SomeDialog.java @@ -1,14 +1,12 @@ package net.rgielen.fxweaver.samples.springboot.starter.controller; +import javafx.application.Platform; import javafx.fxml.FXML; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.VBox; import javafx.stage.Stage; -import net.rgielen.fxweaver.core.FxControllerAndView; -import net.rgielen.fxweaver.core.FxWeaver; import net.rgielen.fxweaver.core.FxmlView; -import org.springframework.beans.factory.InjectionPoint; import org.springframework.stereotype.Component; @@ -31,12 +29,14 @@ public class SomeDialog { @FXML public void initialize() { - this.stage = new Stage(); - stage.setScene(new Scene(dialog)); + Platform.runLater(() -> { + this.stage = new Stage(); + stage.setScene(new Scene(dialog)); - closeButton.setOnAction( + closeButton.setOnAction( actionEvent -> stage.close() - ); + ); + }); } public void show() { diff --git a/samples/springboot-starter-sample/src/main/resources/application.properties b/samples/springboot-starter-sample/src/main/resources/application.properties new file mode 100644 index 0000000..93e00ff --- /dev/null +++ b/samples/springboot-starter-sample/src/main/resources/application.properties @@ -0,0 +1,2 @@ +fxweaver.autoscan.basepackages=net.rgielen.fxweaver.samples.springboot.starter + diff --git a/spring-boot/autoconfigure/src/main/java/net/rgielen/fxweaver/spring/boot/autoconfigure/FxWeaverAutoConfiguration.java b/spring-boot/autoconfigure/src/main/java/net/rgielen/fxweaver/spring/boot/autoconfigure/FxWeaverAutoConfiguration.java index 26b3721..e0508f2 100644 --- a/spring-boot/autoconfigure/src/main/java/net/rgielen/fxweaver/spring/boot/autoconfigure/FxWeaverAutoConfiguration.java +++ b/spring-boot/autoconfigure/src/main/java/net/rgielen/fxweaver/spring/boot/autoconfigure/FxWeaverAutoConfiguration.java @@ -3,17 +3,27 @@ import javafx.fxml.FXMLLoader; import javafx.scene.Node; import net.rgielen.fxweaver.core.FxControllerAndView; +import net.rgielen.fxweaver.core.FxLoadException; import net.rgielen.fxweaver.core.FxWeaver; +import net.rgielen.fxweaver.core.FxmlView; import net.rgielen.fxweaver.spring.InjectionPointLazyFxControllerAndViewResolver; import net.rgielen.fxweaver.spring.SpringFxWeaver; + +import java.util.Arrays; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InjectionPoint; +import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; +import org.springframework.core.type.filter.AnnotationTypeFilter; /** * FxWeaverAutoConfiguration. @@ -27,11 +37,32 @@ SpringFxWeaver.class }) public class FxWeaverAutoConfiguration { - + private static final Logger LOG = LoggerFactory.getLogger(FxWeaverAutoConfiguration.class); + + @Value("${fxweaver.autoscan.basepackages:#{null}}") + private Optional autoScanBasePackages; + @Bean @ConditionalOnMissingBean(FxWeaver.class) public FxWeaver fxWeaver(ConfigurableApplicationContext applicationContext) { - return new SpringFxWeaver(applicationContext); + SpringFxWeaver springFxWeaver = new SpringFxWeaver(applicationContext); + if (this.autoScanBasePackages.isPresent()) { + ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); + scanner.addIncludeFilter(new AnnotationTypeFilter(FxmlView.class)); + Arrays.stream(this.autoScanBasePackages.get()).forEach(autoScanBasePackage -> { + scanner.findCandidateComponents(autoScanBasePackage).forEach(beanDefinition -> { + try { + LOG.info("Initializing fxmlview annnotated bean '{}'...", beanDefinition.getBeanClassName()); + springFxWeaver.load(Class.forName(beanDefinition.getBeanClassName())); + } catch (ClassNotFoundException cnfe) { + throw new FxLoadException(String.format("Class '%s' not found!", beanDefinition.getBeanClassName()), cnfe); + } + }); + }); + } else { + LOG.info("Config property 'fxweaver.autoscan.basepackages' not set, skipping auto fxmlview annotated bean registration."); + } + return springFxWeaver; } @Bean