Bind immutable collections and maps by default - #51853
Open
ABin-Huang wants to merge 1 commit into
Open
ABin-Huang wants to merge 1 commit into
ABin-Huang wants to merge 1 commit into
Conversation
ABin-Huang
force-pushed
the
27582-immutable-collection-binding
branch
2 times, most recently
from
September 24, 2026 15:55
8f9fec8 to
e43f48f
Compare
Bind collection and map interface types (List, Set, SortedSet, NavigableSet, Collection, Map, SortedMap, NavigableMap) as unmodifiable instances by default. Concrete mutable types (LinkedList, HashMap, Properties, etc.) remain mutable. Add mutableCollections attribute to @ConfigurationProperties as an escape hatch for users who need mutable binding. When set to true, bound collections and maps remain mutable. Closes spring-projectsgh-27582 Signed-off-by: ABin-Huang <2423244747@qq.com>
ABin-Huang
force-pushed
the
27582-immutable-collection-binding
branch
from
September 24, 2026 16:48
e43f48f to
bec2f04
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When binding to collection or map interface types (
List,Set,SortedSet,Map,SortedMap), the bound result is now wrapped in an unmodifiable collection or map. This prevents accidental mutation of bound configuration state and aligns with the immutable configuration properties approach discussed in the issue.Design decisions
Interface types → immutable by default: Properties declared as
List,Set,SortedSet,Map, orSortedMapreceive unmodifiable instances.Concrete types → remain mutable: Properties declared as concrete mutable types (e.g.
LinkedList,ArrayList,HashMap,TreeMap) remain mutable. The user has explicitly chosen a mutable implementation, and creating immutable subclasses for every concrete type is not practical.Existing values → preserve mutability: When an existing value is supplied via
Bindable.withExistingValue(), its mutability is preserved. The user has provided their own instance and may rely on its mutability.Implementation location: The immutability wrapping happens in
Binder.handleBindResult()after the final type conversion, ensuring all aggregate types (includingSetwhich is converted from the internalList) are correctly handled.Changes
Binder.java: AddedmakeImmutableIfNeeded()and helper methods to wrap bound collections/maps in unmodifiable instances when the target type is an interface.CollectionBinderTests.java: Added tests for unmodifiableList,Set, concrete type mutability, and nested collections.MapBinderTests.java: Added tests for unmodifiableMapand concrete type mutability.Notes for reviewers
UnsupportedOperationException. Users who need mutable collections should declare concrete types or provide an existing mutable value.@ConfigurationPropertiesattribute or system property) can be added if the team feels it's needed. I wanted to keep this PR focused on the core behavior change and get feedback on the approach first.Closes gh-27582