spring springowire通用转换器如何?

gst*_*low 9 java generics spring spring-mvc autowired

偶尔我注意到有趣的事情:

我已经实现了spring Converter接口:

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

    @Override
    public MyClass2 convert(MyClass1 source) {
       // doesn't matter
    }
}
Run Code Online (Sandbox Code Playgroud)

在控制器中,我像这样自动装配它

@Autowire
Converter<MyClass1, MyClass2> myConverter;
Run Code Online (Sandbox Code Playgroud)

惊喜,但春天注入适当的课程.

根据我的信息,spring在运行时自动装配bean.另外我知道在运行时泛型类型擦除.

我试图了解春天的灵魂,但对我来说很难.

你能解释一下春天如何解决这种情况吗?

Kon*_*kov 5

即使发生了类型擦除,一些类型参数信息实际上并没有被删除,但它在运行时的其他地方相当保留.

对于这堂课:

public class MyConverter implements Converter<MyClass1, MyClass2>
Run Code Online (Sandbox Code Playgroud)

super-interface(Converter)的参数化类型被保留,因为JVM应该知道编译MyConverter实现了一个带有签名的抽象方法,该签名实际上包含这两种类型(MyClass1MyClass2).

为了演示这一点,您可以通过一个简单的main方法尝试以下片段- 这里,在运行时使用Reflection恢复超级接口的参数化信息:

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

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

for (Type argument : types) {
    System.out.println(argument.getTypeName());
}
Run Code Online (Sandbox Code Playgroud)

这些与反射相关的类(Type,ParameterizedType等)是Spring的ResovableType类实际使用的类,它负责根据提供的类型信息检测最佳的布线候选.