简体   繁体   English

class 是如何注入的,它实现了在 Java 或 Groovy 代码中调用的接口方法?

[英]How does class gets injected which implements interface method being called in Java or Groovy code?

I have below working groovy code from Spring framework project:我有以下来自 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;
    }
}

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

Unmarshaller interface is implemented by several classes. Unmarshaller 接口由几个类实现。

Who decides which implementing class to inject during runtime and how it decides which class to use?谁决定在运行时注入哪个实现 class 以及它如何决定使用哪个 class?

Does Spring IoC mechanism does this? Spring IoC 机制是否这样做? If so does it pick up one specific implementing class during build time when jar is generated or it does it during run time?如果是这样,它会在生成 jar 时在构建期间选择一个特定的实现 class 还是在运行时选择它?

Also how to know which implementing class it actually used?另外如何知道它实际使用了哪个实现 class ?

Will above code work outside of Spring in ordinary Java file assuming dependent jars in classpath?假设在类路径中依赖 jars,上面的代码是否可以在普通 Java 文件中的 Spring 之外工作?

As soon as it goes about a Grails project (not a pure Spring one), some things should be clarified.一旦涉及 Grails 项目(不是纯粹的 Spring 项目),就应该澄清一些事情。

Who decides which implementing class to inject during runtime and how it decides which class to use?谁决定在运行时注入哪个实现 class 以及它如何决定使用哪个 class? Does Spring IoC mechanism does this? Spring IoC 机制是否这样做? If so does it pick up one specific implementing class during build time when jar is generated or it does it during run time?如果是这样,它会在生成 jar 时在构建期间选择一个特定的实现 class 还是在运行时选择它?

What Spring does in a plain Spring(Boot) is nicely described by @svr s answer and other documentation on the Inte.net, but has not much to do with your case. @svr 的回答和 Inte.net 上的其他文档很好地描述了 Spring 在普通 Spring(Boot) 中的作用,但与您的情况没有太大关系。

In Grails the convention-over-configuration doctrine is used, meaning that在 Grails 中使用约定优于配置 doctrine,这意味着

  • by default Bean Autowiring is active默认情况下,Bean 自动装配处于活动状态
  • only beans which are declared as Grails artefacts, like Service are auto-injected.只有被声明为 Grails 人工制品的 bean,比如Service才会被自动注入。

Usually, if you want to autowire a bean of other stereotype, you have to declare it somewhere, otherwise Spring IoC container inside Grails simply won't find it.通常,如果你想自动装配其他构造型的 bean,你必须在某处声明它,否则 Grails 中的 Spring IoC 容器根本找不到它。

You shall check your grails-app/conf/spring folder for resources.groovy (or maybe yaml or xml files depending on version ) and see if your unmarshaller bean is defined there.您应该检查您的grails-app/conf/spring文件夹中的resources.groovy (或者可能是 yaml 或 883812976388 文件,具体取决于版本)并查看您的unmarshaller组器 bean 是否在此处定义。 It should look like:它应该看起来像:

beans = {
  unmarshaller Unmarshaller ....
}

So, basically it doesn't matter how many implementations of Unmarshaller interface are present in all project's jar files.因此,基本上所有项目的 jar 文件中有多少Unmarshaller接口的实现并不重要。 The only thing what matters is what defined in your resources.groovy .唯一重要的是您的resources.groovy中定义的内容。

If you want to check the class of the bean in runtime, just log it's class in your service:如果您想在运行时检查 bean 的 class,只需在您的服务中记录它的 class:

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

Who decides which implementing class to inject during runtime and how it decides which class to use?谁决定在运行时注入哪个实现 class 以及它如何决定使用哪个 class? Does Spring IoC mechanism does this? Spring IoC 机制是否这样做? If so does it pick up one specific implementing class during build time when jar is generated or it does it during run time?如果是这样,它会在生成 jar 时在构建期间选择一个特定的实现 class 还是在运行时选择它?

Yes Spring IOC container.是 Spring IOC 容器。 It happens at run time when the application is run.它发生在应用程序运行时的运行时。

Also how to know which implementing class it actually used?另外如何知道它实际使用了哪个实现 class ?

For most part you will have to define bean with implementation to pick.在大多数情况下,您必须定义带有实现的 bean 以供选择。 For other cases you can look at the spring auto configuration classes.对于其他情况,您可以查看 spring 自动配置类。

Will above code work outside of Spring in ordinary Java file assuming dependent jars in classpath?假设在类路径中依赖 jars,上面的代码是否可以在普通 Java 文件中的 Spring 之外工作?

Not sure what you mean outside of Spring but as long as application is packaged correctly it should all work.不确定您在 Spring 之外的意思,但只要应用程序正确打包,它就应该可以正常工作。

Quick Overview快速概览

Spring IOC will only inject a bean when found in the application context. Spring IOC 只会在应用程序上下文中找到时注入一个 bean。 An application context loosely is repository of beans.应用程序上下文松散地是 beans 的存储库。

Classpath Scanning and Registration类路径扫描和注册

Spring scans application to pick up all the stereotyped classes and registers bean definition with application context. Spring 扫描应用程序以获取所有原型类并使用应用程序上下文注册 bean 定义。 Stereotyped annotations include @Component, @Repository, @Service, @Controller, @Configuration.原型注解包括@Component、@Repository、@Service、@Controller、@Configuration。 More

Dependency Injection依赖注入

Spring DI creates the bean and injects them as dependencies into application. Spring DI 创建 bean 并将它们作为依赖项注入到应用程序中。 You can create dependencies between different application components using the registered beans and spring will autowire these for you.您可以使用已注册的 bean 在不同的应用程序组件之间创建依赖关系,spring 将为您自动装配这些依赖关系。 More . More There are two types of DI - Constructor based and setter based - Constructor for required dependencies and setter based for optional dependencies.有两种类型的 DI - 基于构造函数和基于 setter - 必需依赖项的构造函数和可选依赖项基于 setter。 More

There are sensible defaults provided when you use any spring classes.当您使用任何 spring 类时,都会提供合理的默认值。 You just have to define the bean where there is no default or you would like to pick different implementation.您只需要在没有默认值的地方定义 bean,或者您想选择不同的实现。 Application context can be further be enriched by using Spring Boot Auto Configuration where all related classes are wired together to form a coherent entry classes.应用上下文可以通过使用 Spring 引导自动配置进一步丰富,其中所有相关类都连接在一起以形成一个连贯的入口类。 You can then easily inject these into application for getting started.然后,您可以轻松地将它们注入应用程序以开始使用。 More

Example例子

You can define bean in the @Configuration class for a web service module.您可以在@Configuration class 中为 web 服务模块定义 bean。

@Configuration
public class WSConfig {
   @Bean
   public Jaxb2Marshaller marshaller() {
      Jaxb2Marshaller marsharller = new Jaxb2Marshaller();
      marsharller.setContextPath("some package");
   }

   @Bean
   public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller marsharller) {         
      WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marsharller);
   }
}

@RequiredArgsConstructur
public class ItemSearchService  {
    private final Unmarshaller unmarshaller;
    public ItemSearchResponse getObject(InputStream xml) {
       ItemSearchResponse its = null;
       try {
        its = (ItemSearchResponse) unmarshaller.unmarshal(new StreamSource(xml));
        } finally {}
       return its;
    }
 }

This similar configuration is automatically taken care by WebServicesAutoConfiguration with ways to customize when using Spring Boot.这种类似的配置由WebServicesAutoConfiguration自动处理,使用 Spring Boot 时可以自定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何通过接口从实现接口的类调用方法? - How to call a method from a class which implements an interface, through the interface? 如何在实现接口但不扩展另一个类的Java类中引用super方法? - How can I reference a super method in a Java class that implements an interface but does not extend another class? 在Interface中创建一个周期性调用的方法-Java - Create a method in Interface which gets called periodically - Java 如何创建实现接口的抽象类对象(JAVA) - How to create abstract class object which implements interface ( JAVA ) 实现接口方法的类(没有显式实现该接口)是否扩展了该特定接口? - Does a class which implements an interface's method (without explicitly implementing that interface) extend that specific interface? 哪个类在运行时实现接口的方法 - Which class implements interface's method at runtime 哪个类实现了接口操作方法 Perform() - Which class implements Interface Action method Perform() 是否可以在实现接口的 class 中重载方法? - Is it possible to overload a method in a class which implements an Interface? Java方法返回实现接口的枚举 - Java method returns an enum which implements an interface Java实例抽象类,实现接口 - Java instance abstract class, which implements interface
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM