Skip to content

Commit c2d6788

Browse files
nosansbrannen
authored andcommitted
Fix AOT code generation for autowired inner class constructor
Prior to this commit, argument index handling in AutowiredArgumentsCodeGenerator suffered from an off-by-one error when generating code for an autowired inner class constructor. Since the startIndex is already properly calculated for an inner class in InstanceSupplierCodeGenerator.buildGetInstanceMethodForConstructor(...), there is no need to adjust the argument indexes within AutowiredArgumentsCodeGenerator.generateCode(...). Closes gh-34974 Signed-off-by: Dmytro Nosan <[email protected]>
1 parent f207c0e commit c2d6788

File tree

4 files changed

+19
-9
lines changed

4 files changed

+19
-9
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/aot/AutowiredArgumentsCodeGenerator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -68,10 +68,10 @@ public CodeBlock generateCode(Class<?>[] parameterTypes, int startIndex, String
6868
for (int i = startIndex; i < parameterTypes.length; i++) {
6969
code.add(i > startIndex ? ", " : "");
7070
if (!ambiguous) {
71-
code.add("$L.get($L)", variableName, i - startIndex);
71+
code.add("$L.get($L)", variableName, i);
7272
}
7373
else {
74-
code.add("$L.get($L, $T.class)", variableName, i - startIndex, parameterTypes[i]);
74+
code.add("$L.get($L, $T.class)", variableName, i, parameterTypes[i]);
7575
}
7676
}
7777
return code.build();

spring-beans/src/test/java/org/springframework/beans/factory/aot/AutowiredArgumentsCodeGeneratorTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -67,7 +67,7 @@ void generateCodeWhenMultipleArgumentsWithOffset() {
6767
AutowiredArgumentsCodeGenerator generator = new AutowiredArgumentsCodeGenerator(
6868
Outer.Nested.class, constructor);
6969
assertThat(generator.generateCode(constructor.getParameterTypes(), 1))
70-
.hasToString("args.get(0), args.get(1)");
70+
.hasToString("args.get(1), args.get(2)");
7171
}
7272

7373
@Test

spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -133,11 +133,13 @@ void generateWhenHasConstructorWithInnerClassAndDefaultConstructor() {
133133
@Test
134134
void generateWhenHasConstructorWithInnerClassAndParameter() {
135135
BeanDefinition beanDefinition = new RootBeanDefinition(EnvironmentAwareComponent.class);
136+
StandardEnvironment environment = new StandardEnvironment();
136137
this.beanFactory.registerSingleton("configuration", new InnerComponentConfiguration());
137-
this.beanFactory.registerSingleton("environment", new StandardEnvironment());
138+
this.beanFactory.registerSingleton("environment", environment);
138139
compile(beanDefinition, (instanceSupplier, compiled) -> {
139140
Object bean = getBean(beanDefinition, instanceSupplier);
140141
assertThat(bean).isInstanceOf(EnvironmentAwareComponent.class);
142+
assertThat(bean).hasFieldOrPropertyWithValue("environment", environment);
141143
assertThat(compiled.getSourceFile()).contains(
142144
"getBeanFactory().getBean(InnerComponentConfiguration.class).new EnvironmentAwareComponent(");
143145
});
@@ -162,11 +164,13 @@ void generateWhenHasNonPublicConstructorWithInnerClassAndDefaultConstructor() {
162164
@Test
163165
void generateWhenHasNonPublicConstructorWithInnerClassAndParameter() {
164166
BeanDefinition beanDefinition = new RootBeanDefinition(EnvironmentAwareComponentWithoutPublicConstructor.class);
167+
StandardEnvironment environment = new StandardEnvironment();
165168
this.beanFactory.registerSingleton("configuration", new InnerComponentConfiguration());
166-
this.beanFactory.registerSingleton("environment", new StandardEnvironment());
169+
this.beanFactory.registerSingleton("environment", environment);
167170
compile(beanDefinition, (instanceSupplier, compiled) -> {
168171
Object bean = getBean(beanDefinition, instanceSupplier);
169172
assertThat(bean).isInstanceOf(EnvironmentAwareComponentWithoutPublicConstructor.class);
173+
assertThat(bean).hasFieldOrPropertyWithValue("environment", environment);
170174
assertThat(compiled.getSourceFile()).doesNotContain(
171175
"getBeanFactory().getBean(InnerComponentConfiguration.class)");
172176
});

spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/InnerComponentConfiguration.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,7 +28,10 @@ public NoDependencyComponent() {
2828

2929
public class EnvironmentAwareComponent {
3030

31+
final Environment environment;
32+
3133
public EnvironmentAwareComponent(Environment environment) {
34+
this.environment = environment;
3235
}
3336
}
3437

@@ -40,7 +43,10 @@ public class NoDependencyComponentWithoutPublicConstructor {
4043

4144
public class EnvironmentAwareComponentWithoutPublicConstructor {
4245

46+
final Environment environment;
47+
4348
EnvironmentAwareComponentWithoutPublicConstructor(Environment environment) {
49+
this.environment = environment;
4450
}
4551
}
4652

0 commit comments

Comments
 (0)