Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does spring autowire generic converters?

Occasionally I've noticed interesting thing:

I've implemented spring Converter interface:

@Component
public class MyConverter implements Converter<MyClass1, MyClass2> {

    @Override
    public MyClass2 convert(MyClass1 source) {
       // doesn't matter
    }
}

In controller I autowire it like this

@Autowire
Converter<MyClass1, MyClass2> myConverter;

Surprise but spring inject proper class.

According my information spring autowires beans in runtime. Also I know that in Runtime generic types erasure.

I am tried to understand Spring soure but it hard for me.

Can you explain idea how does spring resolve this situation?

like image 575
gstackoverflow Avatar asked Aug 14 '15 10:08

gstackoverflow


1 Answers

Even though type erasure happens, some of the type-parameter information is not actually erased, but it's rather preserved elsewhere at Runtime.

For this class:

public class MyConverter implements Converter<MyClass1, MyClass2>

the parameterized types for the super-interface (Converter) are preserved, because the JVM should know that the compiled MyConverter implements an abstract method with a signature that actually contains these two types (MyClass1 and MyClass2).

In order to demonstrate this, you can try out the following snippet in a simple main method - here, the parameterized information for the super-interface is restored at Runtime with Reflection:

Type[] interfaces = MyConverter.class.getGenericInterfaces();

ParameterizedType interfaceType = (ParameterizedType) interfaces[0];
Type[] types = interfaceType.getActualTypeArguments();

for (Type argument : types) {
    System.out.println(argument.getTypeName());
}

These Reflection-related classes (Type, ParameterizedType, etc.) are the ones which are actually being used by the Spring's ResovableType class, which is responsible for detecting the best candidate for wiring, based on the provided type-information.

like image 78
Konstantin Yovkov Avatar answered Oct 11 '22 01:10

Konstantin Yovkov