当前位置: 首页 > 知识库问答 >
问题:

通用接口的Spring自动布线通用实现

酆出野
2023-03-14

我有个小问题。这可能微不足道,但我以前从未面对过。

我有一个通用接口和它的通用实现。我想自动连线,但发生了错误。以下是详细情况:

接口

@Service
public interface Serializing<T extends Serializable> {
    String serialize(T toBeSerialized);

    T deserialize(String toBeDeserialized, Class<T> resultType);
}

实施

@Service
public class JsonSerializer<T extends Serializable> implements Serializing<T> {
   /** code **/
}

自动布线尝试

private NoteDAO noteDAO;

@Qualifier("jsonSerializer")
private Serializing<UserComment> serializer;

@Autowired
public NoteController(NoteDAO noteDAO, Serializing<UserComment> serializer) {
    this.noteDAO = noteDAO;
    this.serializer = serializer;
}

错误

Parameter 1 of constructor in somepackagepath.NoteController required a bean of type 'anotherpackagepath.Serializing' that could not be found.

我想让它尽可能简单。我已经检查了网络,但是我只发现了在配置中定义我的确切bean。如果可能的话,我更喜欢避免它。

共有3个答案

壤驷宏才
2023-03-14

你必须告诉Spring你想要它自动连接的所有豆子。没有例外。

如果你不能事先说清楚,那么我会说它不适合注射。

您需要完全控制并调用的东西。也许你的情况就是其中之一。这没有错;这只是意味着Spring DI不适合该用例。

宰父俊民
2023-03-14

和java的类型擦除有关:https://docs . Oracle . com/javase/tutorial/Java/generics/erasure . html

java中,您在运行时无法知道泛型类型。唯一的解决方法是使用匿名类或具有非泛型类型的继承类:使用Spring注入匿名类

胡厉刚
2023-03-14

在您的特定情况下,Spring不允许使用泛型类型作为依赖项进行连接,例如:

@Autowired
public NoteController(NoteDAO noteDAO, Serializing<UserComment> serializer) {
    this.noteDAO = noteDAO;
    this.serializer = serializer;
}

原因很简单:一致性
您使用@Service创建Springbean的这个依赖关系:

@Service
public class JsonSerializer<T extends Serializable> implements Serializing<T> {
   /** code **/
}

可以连接到其他豆子中。

想象一下,依赖于序列化实例的bean不使用相同的泛型:序列化

public class Foo{

    @Autowired
    public Foo(NoteDAO noteDAO, Serializing<UserComment> serializer) {
        this.noteDAO = noteDAO;
        this.serializer = serializer;
    }

}
public class Bar{

    @Autowired
    public Bar(NoteDAO noteDAO, Serializing<UserQuestion> serializer) {
        this.noteDAO = noteDAO;
        this.serializer = serializer;
    }

}

这里的< code > serialization 对象是相同的,但是每个bean在。< br >因此它会破坏泛型类型的类型安全。

事实上,删除泛型并不是真正的问题,因为 Spring(从 Spring 4 开始)拥有一个能够解析类型的解析器:

在幕后,新的ResolvableType类提供了实际使用泛型类型的逻辑。您可以自己使用它来轻松导航和解析类型信息。ResolvableType上的大多数方法本身都会返回ResolvableType

在Spring 4之前,您还有其他方法来接受bean依赖项中的泛型类型。< br >真正的问题是,您用< code>@Service注释了一个泛型类,使其成为bean,而它是该泛型类的一个实例,必须将其配置为bean。

因此,要实现您想要执行的操作,请在 @Configuration 类中声明要实例化的 JsonSerializer bean:

@Configuration
public class SerializingBeans {

    @Bean
    public JsonSerializer<UserComment> userCommentSerializer() {
        return new JsonSerializer<UserComment>();
    }

    @Bean
    public JsonSerializer<UserAnswer> userAnswerSerializer() {
        return new JsonSerializer<UserAnswer>();
    }
}

现在,您可以将依赖项连接为泛型类型:

@Service
public class NoteController {

    private Serializing<UserComment> userCommentSerializer;

    @Autowired
    public NoteController(Serializing<UserComment> serializer) {
        this.userCommentSerializer = serializer;

    }
}
 类似资料:
  • 问题内容: 我有一个接口IMenuItem 然后我有一个接口实现 有什么方法可以仅使用IMenuItem接口从配置类创建MenuItem的多个实例?与@autowired之类的?还可以通过指定构造函数的参数来自动装配吗? 问题答案: 实际上适合这种情况。你可以自动连接特定的类(实现)或使用接口。 考虑以下示例: 现在,你可以根据注释值选择对象的名称,从而选择使用其中一种实现方式 像这样: 要多次创

  • 问题内容: 假设我想定义一个接口,该接口代表对远程服务的调用。现在,对远程服务的调用通常会返回一些信息,但也可能包含输入参数。假设一个实现类通常只实现一个服务方法。鉴于上述信息,以下是一个较差的设计(感觉不太正确): 现在,让我们用一个类执行该接口,该类使用输入参数执行远程服务: 关于上述问题,我有两个问题: 如果要提供需要不同输入参数和接口方法返回类型的子类,则使用通用接口()是否合适? 我该如

  • 本文向大家介绍通过C#实现自动售货机接口,包括了通过C#实现自动售货机接口的使用技巧和注意事项,需要的朋友参考一下 下面分几部分介绍C#实现自动售货机接口的方法,代码写的非常详细,不懂的地方有注释可以参考下。 MachineJP类: 第1部分:串口初始化,串口数据读写 第2部分:接收串口数据,并响应货机,向货机发送数据     第3部分:货机状态、投币、出货等接口 ReceiveDataColle

  • 本文向大家介绍TypeScript 通用接口,包括了TypeScript 通用接口的使用技巧和注意事项,需要的朋友参考一下 示例 声明通用接口 具有多个类型参数的通用接口 实施通用接口 用泛型类实现它: 用非泛型类实现它:            

  • 问题内容: 我正在尝试将Spring IoC与这样的接口一起使用: Spring可以基于通用类型参数T提供IoC吗?我的意思是这样的: 当然,上面的例子不起作用: 我的问题:是否可以提供对接口或实现类进行最少修改的类似功能?例如,我知道我可以使用@Qualifiers,但我想使事情尽可能简单。 问题答案: 由于擦除,我认为这是不可能的。在进行全自动布线时,我们通常切换到强类型子接口: 进行此切换后

  • 与属性自动装配相比,构造函数自动装配有什么特殊的优势吗……或者普通的优势。?优于迫使团队在Spring启动中使用构造函数自动装配……它有什么特殊的优势吗?两种类型的自动装配的优缺点