生成器 class 使用 Spring 服务

Builder class using Spring services

我想在 Spring 项目中创建一个构建器 class(即 class 实现构建器设计模式)。 问题是我需要构建器使用一些 Spring 服务。 我显然不希望用户在构造函数中显式提供服务,但是当我尝试 @Autowire 服务时,我得到了 Autowired members must be defined in valid Spring bean。我可以用 @Component 注释我的构建器,但这会使它成为一个单例,这对于构建器来说是不可取的。 如何在不使其成为单例的情况下向我的构建器 class 注入服务?

要使用 this article 中的示例,假设我有以下生成器:

BankAccount account = new BankAccount.Builder(1234L)
            .withOwner(25324)
            .atBranch("Springfield")
            .openingBalance(100)
            .atRate(2.5)
            .build();

我希望 withOwner 使用我的 UserService 从数据库中获取实际用户,给定接收到的 ID 号作为参数。我将如何将 UserService 注入构建器?

有两种方法可以做到这一点:

1) 将服务放入 withOwner() 方法

new BankAccount.Builder(1234L)
            .withOwner(25324, userService)

2) 将 UserService 添加到 Builder 并创建一个构建器工厂:

@Component
class BuilderFactory { 
    @Autowire
    private UserService user service
    BankAccount.Builder newBuilder(Long id) {
        return BankAccount.Builder(service, id);
    }
}

Usage:
    builderFactory.newBuilder(1234L)
                    .withOwner(25324)

How would I go about injecting UserService to builder?

在您的 spring bean 定义中,您不能也不必混合由 Spring 管理的对象和您自己创建的对象,而 Spring 不知道。
虽然你可以让它工作,但它应该只在非常特殊的罕见情况下使用,并且通常出于 legacy/third 方依赖性原因,而不是在你可以更改它的代码中使用。
毫无疑问,您想在 bean 中注入 bean 依赖项。

此运行时错误消息表示您不遵守此规则:

but when I tried to @Autowire the services, I got Autowired members must be defined in valid Spring bean

关于:

I could Annotate my builder with @Component, but that would make it a singleton which will not be desirable for a builder.

singleton 是默认范围,但 Spring 允许您为组件指定其他范围。只需将它定义为 prototype bean,它就会在每次调用时创建一个新实例。

public class BankAccount{

  // ...
  @Component
  @Scope(value="prototype")  
  public static class Builder{
    //...
  }
}