Skip to content

Support null values when binding properties #24133

@chengaofeng

Description

@chengaofeng

Application has a ben annotated with@ConfigurationProperties("test") that has a List<String> attribute called users. at the beginning, one item listed in the external configuration file

test:
  users:
  - Andy

as the application is running, change the configuration file to the following

test:
  users:

or

test:
  users: null

what I expect is users=null or users =[], while the result is still users[0]=Andy

it‘s ok for the following pattern :

test:
  users: ""

Here's a test that fails with Spring Boot 2.1.17.RELEASE

@SpringBootTest(classes=ConfigPropertiesTest.class)
@RunWith(SpringRunner.class)
@EnableConfigurationProperties(ConfigPropertiesTest.TestProperties.class)
@TestPropertySource(properties = {"test.users[0]=Andy"})
public class ConfigPropertiesTest {

    @Autowired
    private TestProperties properties;

    @Autowired
    private ConfigurationPropertiesBindingPostProcessor processor;

    @Autowired
    private ConfigurableEnvironment environment;

    @Test
    public void liveRebindToNull() throws Exception {
        assertEquals(properties.getUsers().get(0),"Andy");
        setNullProperties("test.users");
	assertTrue(environment.getPropertySources().get("test").containsProperty("test.users"));;
        assertNull(environment.getPropertySources().get("test").getProperty("test.users"));
        processor.postProcessBeforeInitialization(properties, "testProperties");
        assertEquals(properties.getUsers().size(), 0); //**_TEST NG_**
    }

    /**
     * TestPropertyValues has no public method set null value, using reflect to do it
     * 
     * @param prefix
     * @throws Exception
     */
    private void setNullProperties(String prefix) throws Exception {
        TestPropertyValues testPropertyValues =  TestPropertyValues.empty();
        Method method = TestPropertyValues.class.getDeclaredMethod("and", Stream.class);
        method.setAccessible(true);

        TestPropertyValues.Pair pair = new TestPropertyValues.Pair(prefix,null);
        testPropertyValues = (TestPropertyValues) method.invoke(testPropertyValues, Stream.of(pair));

        testPropertyValues.applyTo(environment);
    }

    @ConfigurationProperties("test")
    public static class TestProperties {

        private List<String> users;

        public List<String> getUsers() {
            return users;
        }

        public void setUsers(List<String> users) {
            this.users = users;
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions