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;
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
orreturn
type we can inspect the information that's still there. For example, if you look atjava.lang.reflect.Method
you'll see that in addition togetReturnType
that is agetGenericReturnType
method which provides a lot more information. Spring'sResolvableType
just tries to make this information easier to access.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With