如果我在不同的控制器中自动将具有不同类型的通用类连接起来,spring容器会为每个类创建新实例吗?
假设我有一个通用类。
@Component
class MyClass<T, K>{
public K doStuff(T t){
// some logic here
}
}
在控制器中,我使用
@Autowired
MyClass<Employee, Integer> myClass;
,在另一个控制器中,我使用
@Autowired
MyClass<Manager, String> myClass;
答案 0 :(得分:2)
我使用Spring 5.1.6-RELEASE
对其进行了测试。这是代码和输出:
@Component
public class TestClassWithInteger {
private MyClass<Integer, Integer> myClass;
@Autowired
public TestClassWithInteger(MyClass<Integer, Integer> myClass) {
this.myClass = myClass;
this.perform();
}
public void perform() {
System.out.println(myClass);
myClass.doStuff(1);
}
}
@Component
public class TestClassWithString {
private MyClass<String, String> myClass;
@Autowired
public TestClassWithString(MyClass<String, String> myClass) {
this.myClass = myClass;
this.perform();
}
public void perform() {
System.out.println(myClass);
myClass.doStuff("test");
}
}
@Component
class MyClass<T, K>{
public K doStuff(T t){
System.out.println(t);
return null;
}
}
输出为:
test.example.MyClass@841e575
1
test.example.MyClass@841e575
test
如您所见,由于默认情况下泛型bean是单例,因此它是由应用程序上下文返回的-注意,在打印对象时,哈希码的十六进制数是相同的。当我们将MyClass
bean范围更改为原型时,输出为:
test.example.MyClass@533b266e
1
test.example.MyClass@62679465
test
每当为新bean查询应用程序上下文时,都会得到一个新实例。
所以问题的答案:
spring容器是否为属于同一泛型类但使用不同类型的对象创建新的bean?
是:否,不是。
要阐明其工作原理,我们可以参考Phillip Webb发表的here评论:
尽管擦除发生在对象级别,但是字节码中仍然有很多信息。通过从
field
,parameter
或return
类型开始,我们可以检查仍然存在的信息。例如,如果您查看java.lang.reflect.Method
,您会发现除了getReturnType
之外,还有一种getGenericReturnType
方法可以提供更多信息。 Spring的ResolvableType
只是试图使这些信息更易于访问。