如何使用 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();
  }

问题 : 如何将 ServiceAServiceB 注入 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();
    }
}