Lookup method autowiring uses method's result class, not its generic info.
Tested on versions: 5.1.4, 5.3.7, 5.3.8-SNAPSHOT, all affected.
How to reproduce:
package test;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.stereotype.Component;
@Configuration
@ComponentScan(basePackageClasses = App.class)
public class App {
interface A<T> {}
@Bean A<Integer> intA() { return new A<>(){}; }
@Bean A<String> stringA() { return new A<>(){}; }
@Component abstract static class Comp {
private final A<Integer> a1;
Comp(A<Integer> a1) { this.a1 = a1;}
@Lookup("intA") abstract A<Integer> a2();
@Lookup abstract A<Integer> a3();
void test() {
System.out.println(a1.getClass().getName()); // ok
System.out.println(a2().getClass().getName()); // ok
System.out.println(a3().getClass().getName()); // fails, found 2 beans instead of 1
}
}
public static void main(String [] args) {
GenericApplicationContext context = new AnnotationConfigApplicationContext(App.class);
context.getBean(Comp.class).test();
}
}
Fixing proposal :
Index: spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java
===================================================================
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java (revision 93244e9f9d25ea068ab822dd7a0a287e84cf8282)
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java (date 1622203596697)
@@ -25,6 +25,7 @@
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy;
import org.springframework.cglib.core.SpringNamingPolicy;
@@ -35,6 +36,7 @@
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
+import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -244,8 +246,8 @@
return (bean.equals(null) ? null : bean);
}
else {
- return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) :
- this.owner.getBean(method.getReturnType()));
+ ObjectProvider<Object> provider = this.owner.getBeanProvider(ResolvableType.forMethodParameter(method, -1));
+ return argsToUse != null ? provider.getObject(args) : provider.getObject();
}
}
}
Comment From: jhoeller
Thanks for pointing this out! This should be fixed now, please give an upcoming 5.3.8 snapshot a try...