class 如何注入实现在 Java 或 Groovy 代码中调用的接口方法?
How does class gets injected which implements interface method being called in Java or Groovy code?
我有以下来自 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其实就是接口方法:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/oxm/Unmarshaller.html
Unmarshaller 接口由多个 classes 实现。
谁决定在 运行 时间内注入哪个实现 class 以及它如何决定使用哪个 class?
Spring IoC 机制是否这样做?如果是这样,它会在生成 jar 时在构建期间选择一个特定的实现 class 还是在 运行 期间选择一个特定的实现?
还有如何知道它实际使用了哪个实现 class?
上面的代码是否可以在 Spring 之外的普通 Java 文件中工作,假设依赖于 class 路径中的 jar?
Who decides which implementing class to inject during runtime and how
it decides which class to use?
Does Spring IoC mechanism does this? If so does it pick up one
specific implementing class during build time when jar is generated or
it does it during run time?
是 Spring IOC 容器。当应用程序为 运行.
时,它发生在 运行 时间
Also how to know which implementing class it actually used?
在大多数情况下,您必须定义带有实现的 bean 以供选择。对于其他情况,您可以查看 spring 自动配置 classes.
Will above code work outside of Spring in ordinary Java file assuming
dependent jars in classpath?
不确定 Spring 之外的意思,但只要应用程序正确打包,它就应该可以正常工作。
快速概览
Spring IOC 只会在应用程序上下文中找到时注入一个 bean。应用程序上下文松散地是 beans 的存储库。
类路径扫描和注册
Spring 扫描应用程序以获取所有原型 classes 并使用应用程序上下文注册 bean 定义。原型注解包括@Component、@Repository、@Service、@Controller、@Configuration。 More
依赖注入
Spring DI 创建 bean 并将它们作为依赖项注入到应用程序中。您可以使用已注册的 bean 在不同的应用程序组件之间创建依赖关系,spring 将为您自动装配这些依赖关系。 More
. There are two types of DI - Constructor based and setter based - Constructor for required dependencies and setter based for optional dependencies. More
当您使用任何 spring class 时,都会提供合理的默认值。您只需要在没有默认值的地方定义 bean,或者您想选择不同的实现。使用 Spring 引导自动配置可以进一步丰富应用程序上下文,其中所有相关的 classes 都连接在一起以形成一个连贯的条目 classes。然后,您可以轻松地将它们注入应用程序以开始使用。 More
例子
您可以在 @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;
}
}
WebServicesAutoConfiguration
使用 Spring Boot.
自定义方式自动处理此类似配置。
一旦涉及到 Grails 项目(不是纯粹的 Spring 项目),就应该澄清一些事情。
Who decides which implementing class to inject during runtime and how it decides which class to use? Does Spring IoC mechanism does this? If so does it pick up one specific implementing class during build time when jar is generated or it does it during run time?
@svr 的回答和 Internet 上的其他文档很好地描述了 Spring 在普通 Spring(Boot) 中的作用,但与您的情况没有太大关系。
在 Grails 中使用了 convention-over-configuration 原则,这意味着
- 默认情况下,Bean 自动装配处于活动状态
- 只有像
Service
这样被声明为 Grails 工件的 bean 才是 auto-injected。
通常,如果您想自动装配其他构造型的 bean,您必须在某处声明它,否则 SpringGrails 中的 IoC 容器根本找不到它。
您应该检查 grails-app/conf/spring
文件夹中的 resources.groovy
(或者可能是 yaml 或 xml 文件,具体取决于版本)并查看您的 unmarshaller
bean 是否在其中定义。它应该看起来像:
beans = {
unmarshaller Unmarshaller ....
}
所以,基本上所有项目的 jar 文件中有多少 Unmarshaller
接口的实现并不重要。唯一重要的是 resources.groovy
.
中定义的内容
如果您想在运行时检查 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"
}
}
我有以下来自 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其实就是接口方法: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/oxm/Unmarshaller.html
Unmarshaller 接口由多个 classes 实现。
谁决定在 运行 时间内注入哪个实现 class 以及它如何决定使用哪个 class?
Spring IoC 机制是否这样做?如果是这样,它会在生成 jar 时在构建期间选择一个特定的实现 class 还是在 运行 期间选择一个特定的实现?
还有如何知道它实际使用了哪个实现 class?
上面的代码是否可以在 Spring 之外的普通 Java 文件中工作,假设依赖于 class 路径中的 jar?
Who decides which implementing class to inject during runtime and how it decides which class to use? Does Spring IoC mechanism does this? If so does it pick up one specific implementing class during build time when jar is generated or it does it during run time?
是 Spring IOC 容器。当应用程序为 运行.
时,它发生在 运行 时间Also how to know which implementing class it actually used?
在大多数情况下,您必须定义带有实现的 bean 以供选择。对于其他情况,您可以查看 spring 自动配置 classes.
Will above code work outside of Spring in ordinary Java file assuming dependent jars in classpath?
不确定 Spring 之外的意思,但只要应用程序正确打包,它就应该可以正常工作。
快速概览
Spring IOC 只会在应用程序上下文中找到时注入一个 bean。应用程序上下文松散地是 beans 的存储库。
类路径扫描和注册
Spring 扫描应用程序以获取所有原型 classes 并使用应用程序上下文注册 bean 定义。原型注解包括@Component、@Repository、@Service、@Controller、@Configuration。 More
依赖注入
Spring DI 创建 bean 并将它们作为依赖项注入到应用程序中。您可以使用已注册的 bean 在不同的应用程序组件之间创建依赖关系,spring 将为您自动装配这些依赖关系。 More
. There are two types of DI - Constructor based and setter based - Constructor for required dependencies and setter based for optional dependencies. More
当您使用任何 spring class 时,都会提供合理的默认值。您只需要在没有默认值的地方定义 bean,或者您想选择不同的实现。使用 Spring 引导自动配置可以进一步丰富应用程序上下文,其中所有相关的 classes 都连接在一起以形成一个连贯的条目 classes。然后,您可以轻松地将它们注入应用程序以开始使用。 More
例子
您可以在 @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;
}
}
WebServicesAutoConfiguration
使用 Spring Boot.
一旦涉及到 Grails 项目(不是纯粹的 Spring 项目),就应该澄清一些事情。
Who decides which implementing class to inject during runtime and how it decides which class to use? Does Spring IoC mechanism does this? If so does it pick up one specific implementing class during build time when jar is generated or it does it during run time?
@svr 的回答和 Internet 上的其他文档很好地描述了 Spring 在普通 Spring(Boot) 中的作用,但与您的情况没有太大关系。
在 Grails 中使用了 convention-over-configuration 原则,这意味着
- 默认情况下,Bean 自动装配处于活动状态
- 只有像
Service
这样被声明为 Grails 工件的 bean 才是 auto-injected。
通常,如果您想自动装配其他构造型的 bean,您必须在某处声明它,否则 SpringGrails 中的 IoC 容器根本找不到它。
您应该检查 grails-app/conf/spring
文件夹中的 resources.groovy
(或者可能是 yaml 或 xml 文件,具体取决于版本)并查看您的 unmarshaller
bean 是否在其中定义。它应该看起来像:
beans = {
unmarshaller Unmarshaller ....
}
所以,基本上所有项目的 jar 文件中有多少 Unmarshaller
接口的实现并不重要。唯一重要的是 resources.groovy
.
如果您想在运行时检查 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"
}
}