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

时间:2019-07-19 23:23:31

标签: java spring generics inversion-of-control

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

假设我有一个通用类。

@Component
class MyClass<T, K>{

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

}

在控制器中,我使用

@Autowired
MyClass<Employee, Integer> myClass;

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

@Autowired
MyClass<Manager, String> myClass;

1 个答案:

答案 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评论:

  

尽管擦除发生在对象级别,但是字节码中仍然有很多信息。通过从fieldparameterreturn类型开始,我们可以检查仍然存在的信息。例如,如果您查看java.lang.reflect.Method,您会发现除了getReturnType之外,还有一种getGenericReturnType方法可以提供更多信息。 Spring的ResolvableType只是试图使这些信息更易于访问。