[英]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,这意味着
Service
are auto-injected.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.