我有一个使用通过 Spring 注入的多个资源的Builder 。它看起来类似于:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SandBoxBuilder {
private final SandUtil sandUtil;
private Sand sand;
private Box box;
@Autowired
public SandBoxBuilder(SandUtil sandUtil) {
this.sandUtil = sandUtil;
}
public SandBoxBuilder setSand(Sand sand) {
this.sand = sand;
return this;
}
public SandBoxBuilder setBox(Box box) {
this.box = box;
return this;
}
public SandBox build() {
SandBox sandBox = new SandBox(sand);
sandUtil.changeBox(sandBox, box);
return sandBox;
}
}
我遇到的问题是它不是线程安全的。我知道这个构建器不应该是一个单例,但我不确定如何使用弹簧注入的资源(SandUtil
)而不连接构建器并将其注入我使用它的地方。
如何实现一个线程安全的构建器,该构建器利用 spring 注入的单例?
解决方案
由于一些架构限制,我无法将实用程序注入到我的调用类中。我最终实现了一个工厂构建器 bean,它返回一个具有对 spring 资源的引用的构建器的新实例。
解决方案实施
@Component
public class SandBoxBuilderFactory {
private final SandUtil sandUtil;
@Autowired
public SandBoxBuilderFactory(SandUtil sandUtil) {
this.sandUtil = sandUtil;
}
public Builder newBuilder(){
return new Builder(sandUtil);
}
public static class Builder {
private final SandUtil sandUtil;
private Sand sand;
private Box box;
private Builder(SandUtil sandUtil) {
this.sandUtil = sandUtil;
}
public Builder setSand(Sand sand) {
this.sand = sand;
return this;
}
public Builder setBox(Box box) {
this.box = box;
return this;
}
public SandBox build() {
SandBox sandBox = new SandBox(sand);
sandUtil.changeBox(sandBox, box);
return sandBox;
}
}
}
用法
newBuilder().setBox(box).setSand(sand).build();