properties, Class extends DemoConfig> configClass,
+ BeanDefinitionRegistry registry) {
+ String beanName = (String) properties.get("demoName");
+ if (!StringUtils.hasText(beanName)) {
+ BeanDefinitionBuilder builder = rootBeanDefinition(configClass);
+ beanName = BeanDefinitionReaderUtils.generateBeanName(builder.getRawBeanDefinition(), registry);
+ }
+ return beanName;
+ }
+
+}
diff --git a/04fx/demo/src/main/java/io/kimmking/javacourse/demo/EnableDemoConfigBindings.java b/04fx/demo/src/main/java/io/kimmking/javacourse/demo/EnableDemoConfigBindings.java
new file mode 100644
index 00000000..3a002944
--- /dev/null
+++ b/04fx/demo/src/main/java/io/kimmking/javacourse/demo/EnableDemoConfigBindings.java
@@ -0,0 +1,36 @@
+package io.kimmking.javacourse.demo;
+
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * Description for this class.
+ *
+ * @Author : kimmking(kimmking@apache.org)
+ * @create 2022/11/29 16:10
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Import(DemoConfigBindingsRegistrar.class)
+public @interface EnableDemoConfigBindings {
+ /**
+ * The name prefix of the properties that are valid to bind.
+ *
+ * @return the name prefix of the properties to bind
+ */
+ String prefix();
+
+ /**
+ * @return The binding type.
+ */
+ Class extends DemoConfig> type();
+
+ /**
+ * It indicates whether {@link #prefix()} binding to multiple Spring Beans.
+ *
+ * @return the default value is true
+ */
+ boolean multiple() default true;
+}
diff --git a/04fx/demo/src/main/java/io/kimmking/javacourse/demo/PropertySourcesUtils.java b/04fx/demo/src/main/java/io/kimmking/javacourse/demo/PropertySourcesUtils.java
new file mode 100644
index 00000000..f436313e
--- /dev/null
+++ b/04fx/demo/src/main/java/io/kimmking/javacourse/demo/PropertySourcesUtils.java
@@ -0,0 +1,91 @@
+package io.kimmking.javacourse.demo;
+
+
+import org.springframework.core.env.*;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * {@link PropertySources} Utilities
+ *
+ * The source code is cloned from https://github.com/alibaba/spring-context-support/blob/1.0.2/src/main/java/com/alibaba/spring/util/PropertySourcesUtils.java
+ *
+ * @since 2.6.6
+ */
+public abstract class PropertySourcesUtils {
+
+ /**
+ * Get Sub {@link Properties}
+ *
+ * @param propertySources {@link PropertySource} Iterable
+ * @param prefix the prefix of property name
+ * @return Map
+ * @see Properties
+ */
+ public static Map getSubProperties(Iterable> propertySources, String prefix) {
+
+ // Non-Extension AbstractEnvironment
+ AbstractEnvironment environment = new AbstractEnvironment() {
+ };
+
+ MutablePropertySources mutablePropertySources = environment.getPropertySources();
+
+ for (PropertySource> source : propertySources) {
+ mutablePropertySources.addLast(source);
+ }
+
+ return getSubProperties(environment, prefix);
+
+ }
+
+ /**
+ * Get Sub {@link Properties}
+ *
+ * @param environment {@link ConfigurableEnvironment}
+ * @param prefix the prefix of property name
+ * @return Map
+ * @see Properties
+ */
+ public static Map getSubProperties(ConfigurableEnvironment environment, String prefix) {
+
+ Map subProperties = new LinkedHashMap();
+
+ MutablePropertySources propertySources = environment.getPropertySources();
+
+ String normalizedPrefix = normalizePrefix(prefix);
+
+ for (PropertySource> source : propertySources) {
+ if (source instanceof EnumerablePropertySource) {
+ for (String name : ((EnumerablePropertySource>) source).getPropertyNames()) {
+ if (!subProperties.containsKey(name) && name.startsWith(normalizedPrefix)) {
+ String subName = name.substring(normalizedPrefix.length());
+ if (!subProperties.containsKey(subName)) { // take first one
+ Object value = source.getProperty(name);
+ if (value instanceof String) {
+ // Resolve placeholder
+ value = environment.resolvePlaceholders((String) value);
+ }
+ subProperties.put(subName, value);
+ }
+ }
+ }
+ }
+ }
+
+ return Collections.unmodifiableMap(subProperties);
+
+ }
+
+ /**
+ * Normalize the prefix
+ *
+ * @param prefix the prefix
+ * @return the prefix
+ */
+ public static String normalizePrefix(String prefix) {
+ return prefix.endsWith(".") ? prefix : prefix + ".";
+ }
+}
diff --git a/04fx/demo/src/main/resources/application.properties b/04fx/demo/src/main/resources/application.properties
index 8b137891..f7a98d9a 100644
--- a/04fx/demo/src/main/resources/application.properties
+++ b/04fx/demo/src/main/resources/application.properties
@@ -1 +1,9 @@
+demo.config.a1.demoName = d1
+demo.config.a1.demoDesc = demo1
+
+demo.config.a2.demoName = d2
+demo.config.a2.demoDesc = demo2
+
+demo.config.a3.demoName = d3
+demo.config.a3.demoDesc = demo3
\ No newline at end of file
diff --git a/04fx/demo/src/test/java/io/kimmking/javacourse/demo/DemoApplicationTests.java b/04fx/demo/src/test/java/io/kimmking/javacourse/demo/DemoApplicationTests.java
index 23f5cda4..5101ce0e 100644
--- a/04fx/demo/src/test/java/io/kimmking/javacourse/demo/DemoApplicationTests.java
+++ b/04fx/demo/src/test/java/io/kimmking/javacourse/demo/DemoApplicationTests.java
@@ -2,12 +2,50 @@
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.PropertySource;
+
+import java.util.Arrays;
+
+import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class DemoApplicationTests {
-
@Test
- void contextLoads() {
+ void testDemoConfig() {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ context.register(DemoApplication.TestDemoConfig.class);
+ context.refresh();
+
+
+
+ System.out.println(Arrays.toString(context.getBeanNamesForType(DemoConfig.class)));
+ assertEquals(3, context.getBeansOfType(DemoConfig.class).size());
+
+ DemoConfig demoConfig = context.getBean("a1", DemoConfig.class);
+ System.out.println("a1=" + demoConfig.toString());
+ assertEquals("d1", demoConfig.getDemoName());
+ assertEquals("demo1", demoConfig.getDemoDesc());
+
+ demoConfig = context.getBean("a2", DemoConfig.class);
+ System.out.println("a2=" + demoConfig.toString());
+ assertEquals("d2", demoConfig.getDemoName());
+ assertEquals("demo2", demoConfig.getDemoDesc());
+
+ demoConfig = context.getBean("a3", DemoConfig.class);
+ System.out.println("a3=" + demoConfig.toString());
+ assertEquals("d3", demoConfig.getDemoName());
+ assertEquals("demo3", demoConfig.getDemoDesc());
+
+// context.refresh();
+// System.out.println(Arrays.toString(context.getBeanNamesForType(DemoConfig.class)));
+
}
+// @EnableDemoConfigBindings(prefix = "demo.config", type = DemoConfig.class)
+// @PropertySource("application.properties")
+// private static class TestConfig {
+//
+// }
+
}
diff --git a/04fx/spring01/pom.xml b/04fx/spring01/pom.xml
index 505009a7..3075aaf2 100644
--- a/04fx/spring01/pom.xml
+++ b/04fx/spring01/pom.xml
@@ -10,7 +10,7 @@
- 4.3.29.RELEASE
+ 4.3.30.RELEASE
@@ -19,8 +19,8 @@
org.apache.maven.plugins
maven-compiler-plugin
- 8
- 8
+ 11
+ 11