如何使用 Spring 中的注释自动装配第 3 方 类?
How do I autowire 3rd party classes with annotations in Spring?
我发现 Spring Boot 上的大多数示例都集中在构建简单的 Web 应用程序上。也就是说,您可以完全控制一切的 Web 应用程序。
另一方面,我不太幸运地找到了有关如何构建非 Web 应用程序的示例,其中应用程序的大部分依赖于第 3 方代码。
考虑下面我的 com.mypackage.Application
class。
package com.mypackage;
import com.3rdparty.factory.ServiceFactory;
public class Application {
private final ServiceFactory sf;
public Application(ServiceFactory sf) {
this.sf = sf;
}
public void doSomeWork() {
ServiceA sa = sf.getServiceA();
[...]
}
Application
class 只是实例化 DefaultManager
并调用 run()
.
现在,第 3 方 ServiceFactory
class 有额外的依赖项:
package com.3rdparty.factory;
import com.3rdparty.service.ServiceA;
import com.3rdparty.service.ServiceA;
public class ServiceFactory {
private final ServiceA sa;
private final ServiceB sb;
public ServiceFactory(ServiceA sa, ServiceB sb) {
this.sa = sa;
this.sb = sb;
}
public ServiceA getServiceA() {
return sa;
}
public ServiceB getServiceB() {
return sb;
}
}
我可以从 Main
class 启动 Application
:
import com.mypackage.Application;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("path/to/applicationContext.xml");
Application app = (Application) context.getBean("app");
app.doSomeWork();
}
问题 : 如何将 ServiceA
和 ServiceB
注入 ServiceFactory
。这是第 3 方 class,我无法控制它,也无法修改它。因此,我无法添加任何注释。
我可以很容易地使它与 XML 配置一起工作,但考虑到注释似乎是这些天 "best practise" 的做法,我想知道如何获得它使用注释。
如果这样做的注释方式涉及大量代码,那么我想知道与我认为很容易理解的XML配置相比,这给了我什么优势;以及一种易于在不同项目中使用的模式。
您需要定义一个 @Configuration
class 来构建 SomeFactory
作为 Bean:
@Configuration
class SomeFactoryConfiguration {
@Bean
public ServiceFactory serviceFactory() {
return new ServiceFactory(/* create/get ServiceA and ServiceB somehow */):
}
}
这会将此 ServiceFactory 实例公开为您的 spring 应用程序中的 Bean,您可以简单地自动装配。
如果需要,您也可以将 ServiceA 和 ServiceB 创建为 Bean,然后在创建 ServiceFactory 时引用它们:
@Configuration
class SomeFactoryConfiguration {
@Bean
public ServiceFactory serviceFactory() {
return new ServiceFactory(serviceA(), serviceB()):
}
@Bean
public ServiceA serviceA() {
return new ServiceA();
}
@Bean
public ServiceB serviceB() {
return new ServiceB();
}
}
我发现 Spring Boot 上的大多数示例都集中在构建简单的 Web 应用程序上。也就是说,您可以完全控制一切的 Web 应用程序。
另一方面,我不太幸运地找到了有关如何构建非 Web 应用程序的示例,其中应用程序的大部分依赖于第 3 方代码。
考虑下面我的 com.mypackage.Application
class。
package com.mypackage;
import com.3rdparty.factory.ServiceFactory;
public class Application {
private final ServiceFactory sf;
public Application(ServiceFactory sf) {
this.sf = sf;
}
public void doSomeWork() {
ServiceA sa = sf.getServiceA();
[...]
}
Application
class 只是实例化 DefaultManager
并调用 run()
.
现在,第 3 方 ServiceFactory
class 有额外的依赖项:
package com.3rdparty.factory;
import com.3rdparty.service.ServiceA;
import com.3rdparty.service.ServiceA;
public class ServiceFactory {
private final ServiceA sa;
private final ServiceB sb;
public ServiceFactory(ServiceA sa, ServiceB sb) {
this.sa = sa;
this.sb = sb;
}
public ServiceA getServiceA() {
return sa;
}
public ServiceB getServiceB() {
return sb;
}
}
我可以从 Main
class 启动 Application
:
import com.mypackage.Application;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("path/to/applicationContext.xml");
Application app = (Application) context.getBean("app");
app.doSomeWork();
}
问题 : 如何将 ServiceA
和 ServiceB
注入 ServiceFactory
。这是第 3 方 class,我无法控制它,也无法修改它。因此,我无法添加任何注释。
我可以很容易地使它与 XML 配置一起工作,但考虑到注释似乎是这些天 "best practise" 的做法,我想知道如何获得它使用注释。
如果这样做的注释方式涉及大量代码,那么我想知道与我认为很容易理解的XML配置相比,这给了我什么优势;以及一种易于在不同项目中使用的模式。
您需要定义一个 @Configuration
class 来构建 SomeFactory
作为 Bean:
@Configuration
class SomeFactoryConfiguration {
@Bean
public ServiceFactory serviceFactory() {
return new ServiceFactory(/* create/get ServiceA and ServiceB somehow */):
}
}
这会将此 ServiceFactory 实例公开为您的 spring 应用程序中的 Bean,您可以简单地自动装配。
如果需要,您也可以将 ServiceA 和 ServiceB 创建为 Bean,然后在创建 ServiceFactory 时引用它们:
@Configuration
class SomeFactoryConfiguration {
@Bean
public ServiceFactory serviceFactory() {
return new ServiceFactory(serviceA(), serviceB()):
}
@Bean
public ServiceA serviceA() {
return new ServiceA();
}
@Bean
public ServiceB serviceB() {
return new ServiceB();
}
}