支持或反对@service在

时间:2017-04-06 09:44:09

标签: java spring spring-boot

我在专业软件开发领域的编程相当新,我的同事讨论了如何在Spring @Service注释类中使用以下字段:

private static final Map<Key, Value> someMap;
static {
    Map<Key, Value> map = new HashMap<>();
    map.put(aKey, aValue);
    someMap = Collections.unmodifiableMap(map);
}

我可以在不影响以下前提下的某些安全/功能的情况下遗漏任何关键字:

  • 除了直接由具有访问源代码的程序员
  • 之外,永远不会以任何方式修改地图
  • 地图不适用于
  • 以外的任何课程
  • 包含地图的类注释为具有SpringBoot默认范围的服务
  • 编辑假设Key和Value都是Enum值,其中没有任何其他信息或功能。
  • 编辑该地图旨在作为包含切换案例陈述的方法的更好维护替代方案
  • 编辑地图绝不可访问任何其他类

这种方法比使用这样的方法有什么优点或缺点:

private final Map<Key, Value> someMap;

public MyClass() {
    Map<Key, Value> map = new HashMap<>();
    map.put(aKey, aValue);
    someMap = Collections.unmodifiableMap(map);
}

2 个答案:

答案 0 :(得分:1)

您应该问自己的主要问题是您要创建的课程的实例数量。

一个班级实例

@Service的默认范围是单身,那么无论是将地图创建为静态成员还是常规成员,都没有太大区别。只有一个地图实例,唯一的区别在于它的初始化发生的那一刻。使用单例范围没有真正的理由使用静态成员。

但是,通过将地图创建为该类的常规成员,您可以避免将来静态成员出现问题。例如,如果你想对你的类进行单元测试并为某些测试场景存储地图,那么对于静态成员来说会更成问题。静态成员可以从依赖注入和@Value注入中受益,以备不时之需。

许多班级实例

如果更改了@Service类的默认范围,并且您希望所有实例共享一些私有内部状态,那么在某些情况下使用静态成员可能是一个合理的选择。您必须记住,实例可以同时访问或修改地图,因此您应该确保在设计类时考虑到线程安全。

答案 1 :(得分:0)

这两种方法在成员someMap的范围上有所不同;一个是static,另一个是实例成员。这是一个逻辑问题 - 成员应该属于类,或者它应该属于实例。您还没有在特定情况下向我们提供足够的信息,但如果班级的多个实例需要访问课程中的相同地图,那么它显然必须是static 。在这种情况下,实例方法的缺点是程序会中断。 OTOH,如果每个实例都需要自己的地图,那么它就是打破程序的static版本。

所以你告诉我们 - 地图属于班级,还是属于班级的每个实例?

此外,除非其元素也是,否则地图不是不可变的。你无法改变地图中的内容,但是如果这些键是可变的,你可能会得到一些非常奇特的结果。