spring容器是否为属于相同泛型类但使用不同类型的对象创建新的bean?

Let*_*tbe 6 java generics spring inversion-of-control

如果我在不同的控制器中将不同类型的通用类自动装配,spring容器会为每个容器创建新实例吗?

假设我有一个通用类。

@Component
class MyClass<T, K>{

    public K doStuff(T t){
        // some logic here
    }

}
Run Code Online (Sandbox Code Playgroud)

在控制器中,我使用

@Autowired
MyClass<Employee, Integer> myClass;
Run Code Online (Sandbox Code Playgroud)

在另一个控制器中,我使用

@Autowired
MyClass<Manager, String> myClass;
Run Code Online (Sandbox Code Playgroud)

mic*_*alk 3

我使用 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;
    }

}
Run Code Online (Sandbox Code Playgroud)

输出是:

test.example.MyClass@841e575
1
test.example.MyClass@841e575
test
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,由于您的通用 bean 默认情况下是单例,因此它是由应用程序上下文返回的 - 请注意打印对象时哈希码的十六进制 - 它是相同的。当我们将MyClassbean 范围更改为原型时,输出为:

test.example.MyClass@533b266e
1
test.example.MyClass@62679465
test
Run Code Online (Sandbox Code Playgroud)

每当查询应用程序上下文以获取新 bean 时,您都会获得新实例 - 正如预期的那样。

所以问题的答案:

Spring容器是否为属于同一泛型类但使用不同类型的对象创建新的bean?

是:不,不是

为了阐明它是如何工作的,我们可以参考 Phillip Webb在这里发布的评论:

尽管擦除发生在对象级别,但字节码中仍然存在大量信息。通过从field,parameterreturn开始,我们可以检查仍然存在的信息。例如,如果您查看,java.lang.reflect.Method您会发现除此之外还有getReturnType一个getGenericReturnType提供更多信息的方法。SpringResolvableType只是试图让这些信息更容易访问。