Eliminate 2,870 lines of boilerplate using @Mixin annotation processor - #37089
Open
verhasi wants to merge 1 commit into
Open
Eliminate 2,870 lines of boilerplate using @Mixin annotation processor#37089verhasi wants to merge 1 commit into
verhasi wants to merge 1 commit into
Conversation
Apply the Mixin annotation processor to eliminate delegation boilerplate across 50 files in Spring Framework. All changes are compile-time only with zero runtime dependencies. Refactored files (50 total): - spring-web: 11 files including decorators, wrappers, and test utilities - spring-webmvc: 4 files including DelegatingWebMvcConfiguration - spring-websocket: 2 decorators - spring-test: MockWebSession - spring-beans, spring-core, spring-jms, spring-r2dbc, spring-webflux - Plus inner classes and test fixtures Changes: - Add framework-annotation-processor module to claim unclaimed annotations - Add Mixin dependencies to affected modules (compile-time only) - Refactor 50 decorator/wrapper classes to use @mixin - Remove 2,870 lines of forwarding boilerplate - Auto-generate ~750 forwarding methods Technical details: - Zero runtime dependency (compileOnly scope) - All existing tests pass - Generated code is functionally identical to original - No breaking changes to public APIs Benefits: - Reduced maintenance burden for interface changes - Improved code clarity (only business logic visible) - Consistent pattern across all decorators - Zero performance impact This builds on the approach proposed in PR spring-projects#34977 (May 2025), now demonstrated at scale with proven results. Signed-off-by: Verhás István <istvan@verhas.com>
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
This PR eliminates 2,870 lines of delegation boilerplate across 50 files in the Spring Framework using the Mixin annotation processor. All changes are compile-time only with zero runtime dependencies and all existing tests pass.
Motivation
Spring Framework contains significant boilerplate code in decorator and wrapper classes. Analysis identified 141 files with delegation patterns that require ongoing maintenance whenever interfaces change. This PR addresses the highest-impact cases.
Previous Discussion (PR #34977, May 2025)
Last year we proposed this approach for a single file (
MultiValueMapAdapter). The Spring team's feedback was:This PR demonstrates the approach at scale - proving the value and showing minimal complexity.
What Changed
Files Refactored (50 total across 10 modules)
spring-web (11 files)
ClientHttpResponseDecorator(web.client) - 5 methodsClientHttpResponseDecorator(reactive) - 5 methodsClientHttpRequestDecorator(reactive) - 12 methodsEscapedErrors- 17 methodsHttpRequestWrapper- 4 methodsHttpExchangeAdapterDecorator- 6 methodsMockWebSession(testFixtures) - 12 methodsspring-webmvc (4 files)
DelegatingWebMvcConfiguration- 18 methods (complex case with special handling)VersionResourceResolver.FileNameVersionedResource- 16 methods (static inner class)spring-websocket (2 files)
WebSocketSessionDecorator- 17 methodsWebSocketHandlerDecorator- 5 methodsOther modules:
Impact
Technical Details
How Mixin Works
Example
Before:
After:
Build Changes
New module:
framework-annotation-processor-WerrorfailuresDependencies added (per module):
No runtime dependencies -
compileOnlymeans zero runtime impactBenefits
1. Reduced Maintenance Burden
2. Improved Code Clarity
3. Consistency
4. Zero Runtime Cost
Testing
Addressing Previous Concerns
"Build Complexity"
Proven minimal: 50 files refactored, all builds succeed. Standard annotation processing that IDEs handle well.
"Not a Maintenance Problem"
Scale matters: 141 files identified, 2,870 lines of boilerplate. Every interface change requires updating all decorators manually.
"New Dependency"
Compile-time only: Zero runtime dependency. Only adds annotation processor for code generation.
Future Work
This PR addresses 50 of the 141 identified files. Additional candidates remain that could benefit from the same approach, but we chose to demonstrate the pattern first with high-impact, straightforward cases.
Breaking Changes
None. This is purely a refactoring - all public APIs remain identical.
One year ago we proposed this for one file. Today we demonstrate it works at scale across Spring Framework with 2,870 lines eliminated and all tests passing.
We believe this strikes the right balance between reducing maintenance burden and keeping the build straightforward.