【问题标题】:Does spring container create new beans for the objects which belong to same generic class but use different types?spring 容器是否为属于同一泛型类但使用不同类型的对象创建新 bean?
【发布时间】:2019-07-19 23:23:31
【问题描述】:

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

假设我有一个泛型类。

@Component
class MyClass<T, K>{

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

}

在我使用的控制器中

@Autowired
MyClass<Employee, Integer> myClass;

在另一个控制器中我使用

@Autowired
MyClass<Manager, String> myClass;

【问题讨论】:

  • 你试过了吗? (附带说明,不要使用字段注入,因为它有很多问题。改用构造函数注入。)
  • 一个基本功能更新的介绍,旧的但仍然是最常见的情况:spring.io/blog/2013/12/03/…
  • @Deadpool 我认为这不是您链接的问题的重复。我们可以使用@Bean 注解在配置类中创建泛型的bean。但是@Lettibe 正在尝试不同的东西。他正在尝试注释一个 Generic 类并用它制作一个 bean。我从来没有尝试过这样的事情,并且怀疑这是否可能。有人可以对其进行试验并发布结果供我们启发。

标签: java spring generics inversion-of-control


【解决方案1】:

我使用 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 只是试图让这些信息更容易访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    相关资源
    最近更新 更多