Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does spring container create new beans for the objects which belong to same generic class but use different types?

If i autowire my generic class with different types in different controllers, does spring container create new instance for each?

Assume i have a generic class.

@Component
class MyClass<T, K>{

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

}

In a controller i use

@Autowired
MyClass<Employee, Integer> myClass;

and in another controller i use

@Autowired
MyClass<Manager, String> myClass;
like image 783
buraky Avatar asked Jul 19 '19 23:07

buraky


1 Answers

I made a test for it using Spring 5.1.6-RELEASE . Here is the code and output :

@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;
    }

}

The output is :

test.example.MyClass@841e575
1
test.example.MyClass@841e575
test

So as you can see, because of the fact that your generic bean is a singleton by default, it is returned by the application context - notice the hex of hashcode when printing the object - it is the same. When we change MyClass bean scope to prototype then the output is :

test.example.MyClass@533b266e
1
test.example.MyClass@62679465
test

you get new instance whenever application context is queried for a new bean - as expected.

So the answer for the question :

Does spring container create new beans for the objects which belong to same generic class but use different types?

is : No, it does not.

And to shed some light on how it works we can refer to Phillip Webb's comment posted here :

Although erasure happens at the object level, there's a lot of information still in the bytecode. By starting at a field, parameter or return type we can inspect the information that's still there. For example, if you look at java.lang.reflect.Method you'll see that in addition to getReturnType that is a getGenericReturnType method which provides a lot more information. Spring's ResolvableType just tries to make this information easier to access.

like image 138
Michał Krzywański Avatar answered Oct 24 '22 08:10

Michał Krzywański