如何注入实现在 Java 或 Groovy 代码中调用的接口方法的类?

ace*_*ace 5 java grails groovy spring

我有以下来自 Spring 框架项目的工作 groovy 代码:

import org.springframework.oxm.Unmarshaller

public class ItemSearchService  {
    Unmarshaller unmarshaller;
    public ItemSearchResponse getObject(InputStream xml) {
    
        ItemSearchResponse its = null;
        try {
            its = (ItemSearchResponse) unmarshaller.unmarshal(new StreamSource(xml));
        } finally {
        }
        return its;
    }
}
Run Code Online (Sandbox Code Playgroud)

Unmarshaller.unmarshall 其实就是接口方法:https : //docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/oxm/Unmarshaller.html

Unmarshaller 接口由几个类实现。

谁决定在运行时注入哪个实现类以及它如何决定使用哪个类?

Spring IoC 机制有这个功能吗?如果是这样,它是在生成 jar 的构建时间期间选择一个特定的实现类,还是在运行时执行?

另外如何知道它实际使用了哪个实现类?

假设类路径中有依赖的 jar,上面的代码可以在普通 Java 文件中的 Spring 之外工作吗?

inj*_*eer 5

一旦涉及到 Grails 项目(不是纯粹的 Spring 项目),就应该澄清一些事情。

谁决定在运行时注入哪个实现类以及它如何决定使用哪个类?Spring IoC机制是这样做的吗?如果是这样,它会在生成 jar 时的构建期间选取一个特定的实现类,还是在运行时选取一个特定的实现类?

@svr 的回答和互联网上的其他文档很好地描述了 Spring 在普通 Spring(Boot) 中的作用,但与您的情况没有太大关系。

在 Grails 中使用约定优于配置的原则,这意味着

  • 默认情况下 Bean 自动装配处于活动状态
  • 只有被声明为 Grails 工件的 Bean 才会Service被自动注入。

通常,如果您想自动装配其他构造型的 bean,则必须在某处声明它,否则 Grails 内的 Spring IoC 容器根本找不到它。

您应该检查您的grails-app/conf/spring文件夹resources.groovy(或者可能是 yaml 或 xml 文件,具体取决于版本)并查看您的unmarshallerbean 是否在那里定义。它应该看起来像:

beans = {
  unmarshaller Unmarshaller ....
}
Run Code Online (Sandbox Code Playgroud)

Unmarshaller因此,基本上所有项目的 jar 文件中存在多少接口实现并不重要。唯一重要的是你的resources.groovy.

如果你想在运行时检查 bean 的类,只需在你的服务中记录它的类:

class ItemSearchService  {
  Unmarshaller unmarshaller
  ItemSearchResponse getObject(InputStream xml) {
     log.info "unmarshaller's class is $unmarshaller.class"
     // or
     // println "unmarshaller's class is $unmarshaller.class"
  }
}  
Run Code Online (Sandbox Code Playgroud)