java如何避免Spring托管bean和Pojo依赖于同一服务时出现单例
鉴于以下前提条件,我正在寻找单件模式的替代设计:
- 有/有使用某些实用程序服务的Spring管理bean
- 存在/存在使用相同公用事业服务的POJO
- 服务的实现应该易于模拟/交换
有JacksonMapper
实现JsonStringConverter
接口
POJO是一些由构建器模式创建的自定义对象,如下面的示例,它使用接口JsonStringConverter的实现
public class User {
private static final JsonStringConverter jsonStringConverter = JacksonMapper.getInstance();
private String name;
//...
private User (User builder) {
this.name = builder.name;
}
public String getName() {
return name;
}
public String toJson() {
Map<String, String> jsonMap = new LinkedHashMap<String, String>();
jsonMap.put(UserAtributes.NAME.getDescription(), this.name);
return jsonStringConverter.toJson(jsonMap);
}
public static class UserBuilder {
private String name;
//...
public UserBuilder name(String name) {
this.name = name;
return this;
}
public User build() {
return new User(this);
}
}
}
由于User
的实例不是由Spring管理的,因此我无法将JsonStringConverter
的实现注入带有@Autowire
注释的用户
另一方面,有些Spring托管bean使用该接口的相同实现将一些其他映射转换为Json字符串。但由于我已经在SpringIOC外部缓存了一个converter实例,而不是在IOC内部创建一个新对象以供注入,所以我还使用bean中的getInstance()轮询它。这是我一点都不喜欢的部分
这就是问题中的单身汉:
public class JacksonMapper implements JsonStringConverter {
private static final ObjectMapper jsonToMap;
private static final ObjectMapper mapToJson;
private static final JacksonMapper INSTANCE;
static
{
INSTANCE = new JacksonMapper();
jsonToMap = new ObjectMapper();
mapToJson = new ObjectMapper();
}
/**
* Exists to defeat instantiation
*/
private JacksonMapper() {
// not called
}
public static JacksonMapper getInstance() {
return INSTANCE;
}
// methods...
}
我现在看到的选项:
- 让JsonStringConverter与静态方法一起从Json转换为Json。Spring管理的bean和POJO现在可以使用该实用程序类而不是单例李>
缺点:我更喜欢在JsonStringConverter
和客户机代码之间使用显式接口,以便于模拟和交换实现
- 使用单例模式
缺点:要求在内存中有不必要的对象来调用一开始应该是静态的方法
有人能给我指出第三种合理的选择吗
请注意,当Spring管理的bean和POJO都依赖于相同的服务时,这是一个一般性的问题,与这个特定的用例无关
# 1 楼答案
只需将你的单身汉注册为Spring bean:
注意,在这样的情况下,建议将
JacksonMapper
作为enum
模式的一部分,而不是普通类