如何解决如何从单例生成原型对象? 需要设计帮助
| 我是Spring的新手,我陷入了困境。我正在尝试为汽车建模。每个模型都有其自己的构建器对象,并且我有一个BuilderFactory,它根据用户从Web应用程序中的选择返回正确的构建器。 因此,我正在寻找有关如何解决此问题的建议,该问题需要我创建一些单独的车辆,但是我不知道直到运行时我将需要哪种类型的车辆,以及每辆车辆需要对用户而言是唯一的。 我目前所拥有的如下所示。我目前的问题是,因为个体建造者是单身人士,个体车辆也是如此。我需要他们 成为原型。我知道一切看起来都非常糟糕,所以我确定必须有更好的方法来做到这一点。 网络应用程序的顶层看起来像;Vehicle vehicle = vehicleBuilderFactory.getBuilder(platform).build();
我的vehicleBuilderFactory看起来像这样;
@Service
public class VehicleBuilderFactory {
@Autowired
Discovery3Builder discovery3Builder;
@Autowired
Discovery4Builder discovery4Builder;
// Lots of @Autowired statements here.
@Autowired
FreeLander2010Builder freeLander2010Builder;
public VehicleBuilder getBuilder(Platform platform) {
switch (platform.getId()) {
case 1: return discovery3Builder;
case 2: return discovery4Builder;
// Lots of case statements here
case 44: return freeLander2010Builder;
default: return null;
}
}
}
它本身看起来非常恐怖。每个单独的构建者看起来像;
@Service
public class DefenderBuilder implements VehicleBuilder {
@Autowired
Defender defender;
// Loads of Defender specific setters ommitted
@Override
public Vehicle build() {
return defender;
}
}
最后是个人车辆
@Service
@Scope(\"prototype\")
public class Defender extends Vehicle {
}
现在的主要问题是,由于建造者是单身人士,因此车辆也是如此,并且
我需要它们作为原型,因为用户A \的Defender与用户B \的Defender不同。
解决方法
您可以使用Spring \的ObjectFactory使其从单例作用域bean中提供原型作用域bean。用法非常简单:
@Component
class DefenderBuilder implement VechicleBuilder {
@Autowired
ObjectFactory<Defender> defenderFactory;
Defender build() {
return defenderFactory.getObject()
}
}
@Component
@Scope(\"prototype\")
class Defender {
}
每次对DefenderFactory.getObject()的调用都会返回一个新的Defender。
,无需过多了解细节,您说您想从单例生产Prototype bean,可能需要在IoC容器中查找。
Spring文档的3.4.6.1节的Lookup方法注入描述了如何在不丢失控制反转的情况下(即在您的bean不了解bean存储的情况下)完成此操作。
我以前利用ServiceLocatorFactoryBean解决了类似的问题。类级别的Javadoc非常出色,其中包含一些清晰的示例。
,两件事情:
1)您可以使用代理来容纳范围更广的范围更窄的范围(例如,单例的原型)
您所需要做的就是使用相关范围和proxyMode定义原型组件。
您可以在此处阅读有关作用域代理的信息。
2)我注意到的另一件事是您计划使用多个自动装配注释。
请注意,您可以在接口列表上使用自动装配,它将自动装配实现此接口的所有组件,如此处所述。
此外,您可以将平台ID添加到VehicleBuilder接口,然后在构造函数中生成地图,例如:
Map<Integer,VehicleBuilder> vehicleBuilders;
@Autowired
public VehicleBuilderFactory(List<VehicleBuilder> vehicleBuilders) {
this.vehicleBuilders = vehicleBuilders.stream()
.collect(Collectors(x -> x.getPlatformId(),x -> x));
}
这样,您可以避免出现开关情况。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。