From de5a0c3a7beb16d4fd752ae4ef7fc63bc1903899 Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Thu, 30 Oct 2025 16:47:58 +0800 Subject: [PATCH 01/10] Bump project version to 0.2.5-SNAPSHOT Updated the property in pom.xml to prepare for the next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7d87818..061a863 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ - 0.2.4-SNAPSHOT + 0.2.5-SNAPSHOT 17 From edf231adc76ee31afc5da028373d5458bc84dbe0 Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Fri, 7 Nov 2025 15:46:46 +0800 Subject: [PATCH 02/10] Bump microsphere-spring version to 0.2.5 Updated the microsphere-spring.version property in the parent POM from 0.2.4 to 0.2.5 to use the latest release. --- microsphere-spring-boot-parent/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsphere-spring-boot-parent/pom.xml b/microsphere-spring-boot-parent/pom.xml index 45416e6..9c24369 100644 --- a/microsphere-spring-boot-parent/pom.xml +++ b/microsphere-spring-boot-parent/pom.xml @@ -19,7 +19,7 @@ Microsphere Spring Boot Parent - 0.2.4 + 0.2.5 1.7.2 From 2fc6913319702617f3f2d25bb539a933d99af0e4 Mon Sep 17 00:00:00 2001 From: Mercy Ma Date: Fri, 7 Nov 2025 17:03:01 +0800 Subject: [PATCH 03/10] Support array syntax for auto-configuration exclusion Enhanced ConfigurableAutoConfigurationImportFilter to support exclusion of auto-configuration classes using both comma-delimited and array property syntaxes. Refactored exclusion logic to use Binder for array binding and improved placeholder resolution. --- ...igurableAutoConfigurationImportFilter.java | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/autoconfigure/ConfigurableAutoConfigurationImportFilter.java b/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/autoconfigure/ConfigurableAutoConfigurationImportFilter.java index 27453bb..c83e9df 100644 --- a/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/autoconfigure/ConfigurableAutoConfigurationImportFilter.java +++ b/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/autoconfigure/ConfigurableAutoConfigurationImportFilter.java @@ -3,6 +3,7 @@ import io.microsphere.annotation.ConfigurationProperty; import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter; import org.springframework.boot.autoconfigure.AutoConfigurationMetadata; +import org.springframework.boot.context.properties.bind.Binder; import org.springframework.context.EnvironmentAware; import org.springframework.core.Ordered; import org.springframework.core.env.ConfigurableEnvironment; @@ -12,13 +13,15 @@ import java.util.LinkedHashSet; import java.util.Set; -import java.util.TreeSet; import static io.microsphere.annotation.ConfigurationProperty.APPLICATION_SOURCE; +import static io.microsphere.spring.core.env.EnvironmentUtils.asConfigurableEnvironment; +import static io.microsphere.util.ArrayUtils.EMPTY_STRING_ARRAY; import static io.microsphere.util.ArrayUtils.combine; import static java.util.Arrays.asList; import static java.util.Collections.emptySet; import static java.util.Collections.unmodifiableSet; +import static org.springframework.boot.context.properties.bind.Binder.get; import static org.springframework.util.Assert.isInstanceOf; import static org.springframework.util.StringUtils.collectionToCommaDelimitedString; import static org.springframework.util.StringUtils.commaDelimitedListToSet; @@ -32,6 +35,11 @@ *
{@code
  * microsphere.autoconfigure.exclude=com.example.FooAutoConfiguration,com.example.BarAutoConfiguration
  * }
+ * or + *
{@code
+ * microsphere.autoconfigure.exclude[0]=com.example.FooAutoConfiguration
+ * microsphere.autoconfigure.exclude[1]=com.example.BarAutoConfiguration
+ * }
* *

Programmatically exclude classes

*
{@code
@@ -70,18 +78,39 @@ public void setEnvironment(Environment environment) {
     }
 
     public static Set getExcludedAutoConfigurationClasses(Environment environment) {
-        MutablePropertySources propertySources = getPropertySources(environment);
-        Set allExcludedClasses = new TreeSet<>();
+        ConfigurableEnvironment configurableEnvironment = asConfigurableEnvironment(environment);
+        Set allExcludedClasses = new LinkedHashSet<>();
+        addExcludedAutoConfigurationClasses(environment, getExcludedAutoConfigurationClasses(configurableEnvironment), allExcludedClasses);
+        addExcludedAutoConfigurationClasses(environment, getExcludedAutoConfigurationClassesFromBinder(configurableEnvironment), allExcludedClasses);
+        return allExcludedClasses.isEmpty() ? emptySet() : unmodifiableSet(allExcludedClasses);
+    }
+
+    private static void addExcludedAutoConfigurationClasses(Environment environment, String[] excludedClasses,
+                                                            Set allExcludedClasses) {
+        for (String excludedClass : excludedClasses) {
+            String resolvedExcludeClass = environment.resolvePlaceholders(excludedClass);
+            allExcludedClasses.addAll(commaDelimitedListToSet(resolvedExcludeClass));
+        }
+    }
+
+    private static String[] getExcludedAutoConfigurationClasses(ConfigurableEnvironment environment) {
+        Set excludedClasses = new LinkedHashSet<>();
+        MutablePropertySources propertySources = environment.getPropertySources();
         for (PropertySource propertySource : propertySources) {
             Object property = propertySource.getProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME);
             if (property instanceof String) {
                 String exclude = (String) property;
                 String resolvedExclude = environment.resolvePlaceholders(exclude);
-                Set excludedClasses = commaDelimitedListToSet(resolvedExclude);
-                allExcludedClasses.addAll(excludedClasses);
+                Set classes = commaDelimitedListToSet(resolvedExclude);
+                excludedClasses.addAll(classes);
             }
         }
-        return allExcludedClasses.isEmpty() ? emptySet() : unmodifiableSet(allExcludedClasses);
+        return excludedClasses.isEmpty() ? EMPTY_STRING_ARRAY : excludedClasses.toArray(EMPTY_STRING_ARRAY);
+    }
+
+    private static String[] getExcludedAutoConfigurationClassesFromBinder(ConfigurableEnvironment environment) {
+        Binder binder = get(environment);
+        return binder.bind(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, String[].class).orElse(EMPTY_STRING_ARRAY);
     }
 
     /**

From ac7529f2e1d3aabbb6994fb1b465d22dcbec6bc4 Mon Sep 17 00:00:00 2001
From: Mercy Ma 
Date: Fri, 7 Nov 2025 17:03:10 +0800
Subject: [PATCH 04/10] Enhance tests for auto-configuration exclusion logic

Refactored ConfigurableAutoConfigurationImportFilterTest to improve readability and reuse of test setup. Added new test cases for exclusion via property sources and binder array properties, and consolidated environment and filter initialization.
---
 ...ableAutoConfigurationImportFilterTest.java | 125 +++++++++++-------
 1 file changed, 80 insertions(+), 45 deletions(-)

diff --git a/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/autoconfigure/ConfigurableAutoConfigurationImportFilterTest.java b/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/autoconfigure/ConfigurableAutoConfigurationImportFilterTest.java
index 9891fb2..f88cc29 100644
--- a/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/autoconfigure/ConfigurableAutoConfigurationImportFilterTest.java
+++ b/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/autoconfigure/ConfigurableAutoConfigurationImportFilterTest.java
@@ -18,11 +18,14 @@
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.core.env.MutablePropertySources;
 import org.springframework.mock.env.MockEnvironment;
 
 import java.util.Set;
 import java.util.TreeSet;
 
+import static io.microsphere.collection.Maps.ofMap;
 import static io.microsphere.spring.boot.autoconfigure.ConfigurableAutoConfigurationImportFilter.AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME;
 import static io.microsphere.spring.boot.autoconfigure.ConfigurableAutoConfigurationImportFilter.addExcludedAutoConfigurationClass;
 import static io.microsphere.spring.boot.autoconfigure.ConfigurableAutoConfigurationImportFilter.getExcludedAutoConfigurationClasses;
@@ -50,9 +53,15 @@ class ConfigurableAutoConfigurationImportFilterTest {
 
     private MockEnvironment environment;
 
+    private String[] autoConfigurationClasses;
+
+    private ConfigurableAutoConfigurationImportFilter filter;
+
     @BeforeEach
     void setUp() {
-        environment = new MockEnvironment();
+        this.environment = new MockEnvironment();
+        this.autoConfigurationClasses = ofArray(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3);
+        this.filter = new ConfigurableAutoConfigurationImportFilter();
     }
 
     @Test
@@ -62,97 +71,123 @@ void testConstants() {
 
     @Test
     void testMatch() {
-        ConfigurableAutoConfigurationImportFilter filter = new ConfigurableAutoConfigurationImportFilter();
-        filter.setEnvironment(this.environment);
-
-        String[] autoConfigurationClasses = ofArray(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3);
-
-        boolean[] result = filter.match(autoConfigurationClasses, null);
+        this.filter.setEnvironment(this.environment);
+        boolean[] result = this.filter.match(this.autoConfigurationClasses, null);
         assertTrue(result[0]);
         assertTrue(result[1]);
         assertTrue(result[2]);
 
         this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1);
-        filter.setEnvironment(this.environment);
-        result = filter.match(autoConfigurationClasses, null);
+        this.filter.setEnvironment(this.environment);
+        result = this.filter.match(this.autoConfigurationClasses, null);
         assertFalse(result[0]);
         assertTrue(result[1]);
         assertTrue(result[2]);
+
+        MutablePropertySources propertySources = this.environment.getPropertySources();
+        MapPropertySource mapPropertySource1 = new MapPropertySource("map-property-source-1",
+                ofMap(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_2));
+        propertySources.addLast(mapPropertySource1);
+        this.filter.setEnvironment(this.environment);
+        result = this.filter.match(this.autoConfigurationClasses, null);
+        assertFalse(result[0]);
+        assertFalse(result[1]);
+        assertTrue(result[2]);
+
+        MapPropertySource mapPropertySource2 = new MapPropertySource("map-property-source-2",
+                ofMap(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_3));
+        propertySources.addLast(mapPropertySource2);
+        this.filter.setEnvironment(this.environment);
+        result = this.filter.match(this.autoConfigurationClasses, null);
+        assertFalse(result[0]);
+        assertFalse(result[1]);
+        assertFalse(result[2]);
+    }
+
+    @Test
+    void testMatchFromBinder() {
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME + "[0]", TEST_CLASS_NAME_1);
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME + "[1]", TEST_CLASS_NAME_2);
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME + "[2]", TEST_CLASS_NAME_3);
+        this.filter.setEnvironment(this.environment);
+        boolean[] result = this.filter.match(autoConfigurationClasses, null);
+        assertFalse(result[0]);
+        assertFalse(result[1]);
+        assertFalse(result[2]);
     }
 
     @Test
     void testGetExcludedAutoConfigurationClasses() {
-        Set classNames = getExcludedAutoConfigurationClasses(environment);
+        Set classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertTrue(classNames.isEmpty());
 
-        environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1);
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1);
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(singleton(TEST_CLASS_NAME_1), classNames);
 
-        environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_2);
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_2);
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2)), classNames);
 
-        environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_2 + "," + TEST_CLASS_NAME_3);
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_2 + "," + TEST_CLASS_NAME_3);
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3)), classNames);
 
         // Test the placeholders
-        environment.setProperty("exclude", TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_3);
-        environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, "${exclude}");
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        this.environment.setProperty("exclude", TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_3);
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, "${exclude}");
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_3)), classNames);
 
-        environment.setProperty("exclude1", TEST_CLASS_NAME_1);
-        environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_2 + ",${exclude1}");
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        this.environment.setProperty("exclude1", TEST_CLASS_NAME_1);
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_2 + ",${exclude1}");
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(new TreeSet(asList(TEST_CLASS_NAME_2, TEST_CLASS_NAME_1)), classNames);
 
-        environment.setProperty("exclude1", TEST_CLASS_NAME_1);
-        environment.setProperty("exclude2", TEST_CLASS_NAME_2);
-        environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, "${exclude1},${exclude2}");
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        this.environment.setProperty("exclude1", TEST_CLASS_NAME_1);
+        this.environment.setProperty("exclude2", TEST_CLASS_NAME_2);
+        this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, "${exclude1},${exclude2}");
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2)), classNames);
     }
 
     @Test
     void testAddExcludedAutoConfigurationClass() {
-        Set classNames = getExcludedAutoConfigurationClasses(environment);
+        Set classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertTrue(classNames.isEmpty());
 
-        addExcludedAutoConfigurationClass(environment, TEST_CLASS_NAME_1);
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        addExcludedAutoConfigurationClass(this.environment, TEST_CLASS_NAME_1);
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(singleton(TEST_CLASS_NAME_1), classNames);
 
-        addExcludedAutoConfigurationClass(environment, TEST_CLASS_NAME_2);
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        addExcludedAutoConfigurationClass(this.environment, TEST_CLASS_NAME_2);
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2)), classNames);
 
         // Test the placeholders
-        environment.setProperty("exclude3", TEST_CLASS_NAME_3);
-        addExcludedAutoConfigurationClass(environment, "${exclude3}");
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        this.environment.setProperty("exclude3", TEST_CLASS_NAME_3);
+        addExcludedAutoConfigurationClass(this.environment, "${exclude3}");
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3)), classNames);
 
         // Test the duplicated elements
-        addExcludedAutoConfigurationClass(environment, TEST_CLASS_NAME_3);
-        classNames = getExcludedAutoConfigurationClasses(environment);
+        addExcludedAutoConfigurationClass(this.environment, TEST_CLASS_NAME_3);
+        classNames = getExcludedAutoConfigurationClasses(this.environment);
         assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3)), classNames);
     }
 
     @Test
     void testIsExcluded() {
-        ConfigurableAutoConfigurationImportFilter filter = new ConfigurableAutoConfigurationImportFilter();
-        filter.setEnvironment(this.environment);
+        this.filter.setEnvironment(this.environment);
 
-        assertFalse(filter.isExcluded(null));
-        assertFalse(filter.isExcluded(""));
-        assertFalse(filter.isExcluded(" "));
+        assertFalse(this.filter.isExcluded(null));
+        assertFalse(this.filter.isExcluded(""));
+        assertFalse(this.filter.isExcluded(" "));
 
-        assertFalse(filter.isExcluded(TEST_CLASS_NAME_1));
+        assertFalse(this.filter.isExcluded(TEST_CLASS_NAME_1));
 
-        addExcludedAutoConfigurationClass(environment, TEST_CLASS_NAME_1);
-        filter.setEnvironment(this.environment);
-        assertTrue(filter.isExcluded(TEST_CLASS_NAME_1));
+        addExcludedAutoConfigurationClass(this.environment, TEST_CLASS_NAME_1);
+        this.filter.setEnvironment(this.environment);
+        assertTrue(this.filter.isExcluded(TEST_CLASS_NAME_1));
     }
 }
\ No newline at end of file

From bdf139bd88df14b798684cbc3f07591798903474 Mon Sep 17 00:00:00 2001
From: Mercy Ma 
Date: Fri, 7 Nov 2025 17:23:02 +0800
Subject: [PATCH 05/10] Add Spring Boot 4.0 profile and milestone repo support

Introduces a new Maven profile for Spring Boot 4.0 and adds the Spring milestone repository to support pre-release dependencies. Also removes distribution and snapshot repository configuration from the root pom.xml to streamline project setup.
---
 .github/workflows/maven-build.yml      |  4 +++-
 microsphere-spring-boot-parent/pom.xml | 15 +++++++++++++++
 pom.xml                                | 24 ------------------------
 3 files changed, 18 insertions(+), 25 deletions(-)

diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml
index a7068ad..9f54a8c 100644
--- a/.github/workflows/maven-build.yml
+++ b/.github/workflows/maven-build.yml
@@ -21,7 +21,9 @@ jobs:
       matrix:
         java: [ '17' , '21' , '25' ]
         maven-profile-spring-boot: [ 'spring-boot-3.0' , 'spring-boot-3.1' , 'spring-boot-3.2' ,
-                                     'spring-boot-3.3' , 'spring-boot-3.4' ]
+                                     'spring-boot-3.3' , 'spring-boot-3.4' ,
+                                     'spring-boot-4.0'
+        ]
     steps:
       - name: Checkout Source
         uses: actions/checkout@v4
diff --git a/microsphere-spring-boot-parent/pom.xml b/microsphere-spring-boot-parent/pom.xml
index 9c24369..106d01b 100644
--- a/microsphere-spring-boot-parent/pom.xml
+++ b/microsphere-spring-boot-parent/pom.xml
@@ -45,6 +45,14 @@
         
     
 
+    
+        
+            spring-milestone
+            Spring Portfolio Milestone Repository
+            https://repo.spring.io/milestone
+        
+    
+
     
         
             spring-boot-3.0
@@ -90,5 +98,12 @@
                 3.5.7
             
         
+
+        
+            spring-boot-4.0
+            
+                4.0.0-RC2
+            
+        
     
 
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 061a863..92b4b4f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,28 +62,4 @@
         microsphere-spring-boot-actuator
     
 
-    
-        
-            ossrh
-            https://s01.oss.sonatype.org/content/repositories/snapshots
-        
-        
-            ossrh
-            https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
-        
-    
-
-    
-        
-            snapshot
-            
-                true
-            
-            
-                false
-            
-            https://s01.oss.sonatype.org/content/repositories/snapshots
-        
-    
-
 
\ No newline at end of file

From 465b094d93cd2e76631d1df5944beff983255017 Mon Sep 17 00:00:00 2001
From: Mercy Ma 
Date: Fri, 7 Nov 2025 19:41:05 +0800
Subject: [PATCH 06/10] Remove spring-boot-4.0 from Maven build matrix

The spring-boot-4.0 profile has been removed from the GitHub Actions Maven build matrix, likely due to incompatibility or lack of support at this time.
---
 .github/workflows/maven-build.yml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml
index 9f54a8c..a418f20 100644
--- a/.github/workflows/maven-build.yml
+++ b/.github/workflows/maven-build.yml
@@ -21,8 +21,7 @@ jobs:
       matrix:
         java: [ '17' , '21' , '25' ]
         maven-profile-spring-boot: [ 'spring-boot-3.0' , 'spring-boot-3.1' , 'spring-boot-3.2' ,
-                                     'spring-boot-3.3' , 'spring-boot-3.4' ,
-                                     'spring-boot-4.0'
+                                     'spring-boot-3.3' , 'spring-boot-3.4'
         ]
     steps:
       - name: Checkout Source

From 7caeed25118552393dd7b2e8b6c7a6c5fcdc059f Mon Sep 17 00:00:00 2001
From: Mercy Ma 
Date: Fri, 7 Nov 2025 19:48:16 +0800
Subject: [PATCH 07/10] Add unit test for SpringBootPropertyConstants

Introduces SpringBootPropertyConstantsTest to verify the values of constants in SpringBootPropertyConstants, ensuring correctness and alignment with expected property names.
---
 .../SpringBootPropertyConstantsTest.java      | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/constants/SpringBootPropertyConstantsTest.java

diff --git a/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/constants/SpringBootPropertyConstantsTest.java b/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/constants/SpringBootPropertyConstantsTest.java
new file mode 100644
index 0000000..81e2667
--- /dev/null
+++ b/microsphere-spring-boot-core/src/test/java/io/microsphere/spring/boot/constants/SpringBootPropertyConstantsTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.microsphere.spring.boot.constants;
+
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
+
+import static io.microsphere.reflect.FieldUtils.getStaticFieldValue;
+import static io.microsphere.spring.boot.constants.SpringBootPropertyConstants.ATTACHED_PROPERTY_SOURCE_NAME;
+import static io.microsphere.spring.boot.constants.SpringBootPropertyConstants.SPRING_AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link SpringBootPropertyConstants} Test
+ *
+ * @author Mercy
+ * @see SpringBootPropertyConstants
+ * @since 1.0.0
+ */
+class SpringBootPropertyConstantsTest {
+
+    @Test
+    void testConstants() {
+        assertEquals("spring.autoconfigure.exclude", SPRING_AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME);
+
+        assertEquals("configurationProperties", ATTACHED_PROPERTY_SOURCE_NAME);
+        assertEquals(getStaticFieldValue(ConfigurationPropertySources.class, "ATTACHED_PROPERTY_SOURCE_NAME"), ATTACHED_PROPERTY_SOURCE_NAME);
+    }
+
+}
\ No newline at end of file

From 8797b86b13fdb0ea9480c51d56add3bf870db513 Mon Sep 17 00:00:00 2001
From: Mercy Ma 
Date: Fri, 7 Nov 2025 19:48:22 +0800
Subject: [PATCH 08/10] Use EMPTY_STRING constant in binder.bind call

Replaces the hardcoded empty string with the EMPTY_STRING constant from StringUtils in the binder.bind method for improved code clarity and consistency.
---
 .../boot/context/config/BindableConfigurationBeanBinder.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/config/BindableConfigurationBeanBinder.java b/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/config/BindableConfigurationBeanBinder.java
index 90e030a..93dc879 100644
--- a/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/config/BindableConfigurationBeanBinder.java
+++ b/microsphere-spring-boot-core/src/main/java/io/microsphere/spring/boot/context/config/BindableConfigurationBeanBinder.java
@@ -31,7 +31,7 @@
 
 import static io.microsphere.collection.Lists.ofList;
 import static io.microsphere.spring.boot.context.properties.bind.util.BindHandlerUtils.createBindHandler;
-import static java.util.Arrays.asList;
+import static io.microsphere.util.StringUtils.EMPTY_STRING;
 import static org.springframework.boot.context.properties.bind.Bindable.ofInstance;
 import static org.springframework.boot.context.properties.source.ConfigurationPropertySources.from;
 
@@ -81,6 +81,6 @@ public void bind(Map configurationProperties, boolean ignoreUnkn
         BindHandler bindHandler = createBindHandler(ignoreUnknownFields, ignoreInvalidFields);
 
         // Bind
-        binder.bind("", bindable, bindHandler);
+        binder.bind(EMPTY_STRING, bindable, bindHandler);
     }
 }
\ No newline at end of file

From cf4005aca3cde16e2979feac427aa717da71935f Mon Sep 17 00:00:00 2001
From: Mercy Ma 
Date: Fri, 7 Nov 2025 20:52:00 +0800
Subject: [PATCH 09/10] Update latest version numbers in README

Bumped the latest version numbers for branches 0.2.x and 0.1.x in the README to reflect recent releases.
---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 879c614..ad05042 100644
--- a/README.md
+++ b/README.md
@@ -62,8 +62,8 @@ pom.xml:
 
 | **Branches** | **Purpose**                               | **Latest Version** |
 |--------------|-------------------------------------------|--------------------|
-| **0.2.x**    | Compatible with Spring Boot 3.0.x - 3.5.x | 0.2.4              |
-| **0.1.x**    | Compatible with Spring Boot 2.0.x - 2.7.x | 0.1.4              |
+| **0.2.x**    | Compatible with Spring Boot 3.0.x - 3.5.x | 0.2.5              |
+| **0.1.x**    | Compatible with Spring Boot 2.0.x - 2.7.x | 0.1.5              |
 
 Then add the specific modules you need:
 

From 7c7c24146f7fcdc9f1cf38131b608074683def96 Mon Sep 17 00:00:00 2001
From: Mercy Ma 
Date: Fri, 7 Nov 2025 20:54:06 +0800
Subject: [PATCH 10/10] Remove isitmaintained badges from README

Deleted badges for average issue resolution time and percentage of open issues from the README. This simplifies the badge section and removes external isitmaintained references.
---
 README.md | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/README.md b/README.md
index ad05042..b80dfc2 100644
--- a/README.md
+++ b/README.md
@@ -8,8 +8,7 @@
 [![Codecov](https://codecov.io/gh/microsphere-projects/microsphere-spring-boot/branch/dev/graph/badge.svg)](https://app.codecov.io/gh/microsphere-projects/microsphere-spring-boot)
 ![Maven](https://img.shields.io/maven-central/v/io.github.microsphere-projects/microsphere-spring-boot.svg)
 ![License](https://img.shields.io/github/license/microsphere-projects/microsphere-spring-boot.svg)
-[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/microsphere-projects/microsphere-spring-boot.svg)](http://isitmaintained.com/project/microsphere-projects/microsphere-spring-boot "Average time to resolve an issue")
-[![Percentage of issues still open](http://isitmaintained.com/badge/open/microsphere-projects/microsphere-spring-boot.svg)](http://isitmaintained.com/project/microsphere-projects/microsphere-spring-boot "Percentage of issues still open")
+
 
 Microsphere Spring Boot is a collection of libraries that extends Spring Boot's capabilities with additional features
 focused on configuration management, application diagnostics, and enhanced monitoring. The project is structured as a