【问题标题】:Should I use static at all in spring singleton beans我应该在春季单例豆中使用静态吗
【发布时间】:2020-10-10 01:05:16
【问题描述】:

正如我刚刚读到的,默认我创建的 spring bean 是 Singletons。我目前正在为我的 Loggers、重用变量和一些我只想存在一次的 List 使用 static 关键字。

但是因为所有 bean 都是单例,所以我正在考虑从所有内容中删除静态。

private static final Logger LOGGER = LoggerFactory.getLogger(MatchmakingService.class);
private static final List<Lobby> QUEUE_BLOCKED = new ArrayList<>();

private final Logger logger = LoggerFactory.getLogger(MatchmakingService.class);
private final List<Lobby> queueBlocked = new ArrayList<>();

我的问题是,我应该在 spring 上下文中使用“静态”吗?如果是,为什么?

【问题讨论】:

    标签: java spring static singleton javabeans


    【解决方案1】:

    Spring 的设计是为了在绝大多数情况下可以避免使用静态字段。

    拥有一个静态最终的记录器是完全可以的。记录器是线程安全的,旨在以这种方式使用。

    拥有静态最终常量是可以的。

    除了记录器,应该避免任何不可变的静态。

    也不要将实例变量用于会话状态(与服务调用者执行的操作相关的状态),因为其他调用者可以访问和更改该状态。

    如果您使用实例或静态变量进行缓存,请摆脱它们并改为配置缓存管理器。

    如果您的代码将配置数据存储在静态字段中,请将它们设为实例字段并使用 spring 读取配置数据。

    【讨论】:

    • 好的,我将保持这些静态。我认为我正在编写的应用程序不够大,不需要缓存管理器。我目前正在将数据存储在实例 ArrayLists 中。我没有操纵其他班级的那些,所以如果我错了,请纠正我,但这应该没问题。
    • @Jan:让 spring 在代码之外处理缓存的好处是,您可以在不更改代码的情况下修改缓存的工作方式。本地缓存代码通常不灵活且脆弱。可能值得一试。
    • 是的,你是对的。尽管在我的业务案例中,我宁愿“存储”我的对象而不是“缓存”它们以便以后重用它们。 (如果这是对缓存的正确理解。)我只是不将它们放入数据库中,因为在程序关闭的情况下它们可能会丢失。但我想我在这里说得太具体了。谢谢你的回答!
    • 明确指出静态 state 作为问题会更清楚一点(因为记录器不是状态)。
    • @chrylis-cautiouslyoptimistic- 是的,你是对的。不过,原来的答案还是合适的。
    【解决方案2】:

    在一个类中使用静态记录器通常是有意义的,如果它记录到同一个文件或输出流(例如System.out),无论哪个实例记录一些东西。代码片段中的队列是否应该是静态的,取决于它的用途,如果没有更多详细信息就无法回答。

    【讨论】:

      【解决方案3】:

      好问题。在我看来,如果您的业务场景始终处于相同的 spring 上下文中,则不应使用静态。原因是 spring bean 在一个 spring 上下文中是单一的。但是 bean 在不同的 spring 上下文中具有不同的实例。以下是示例代码:

      //  The first Spring Bean Context
      ApplicationContext context1 = new FileSystemXmlApplicationContext("classpath:/ApplicationContext.xml");
      Biz b1 = context1.getBean("myBean", Biz.class);
      
      //  The second Spring Bean Context
      ApplicationContext context2 = new FileSystemXmlApplicationContext("classpath:/ApplicationContext.xml");
      Biz b2 = context2.getBean("myBean", Biz.class);
      
      //  The result is false, because of creating two instances of Biz
      System.out.println(b1 == b2);
      

      但是静态变量在一个 JVM 中只有一个实例。所以为了性能和健壮,你应该更频繁地使用静态。换句话说,你不能在一个程序中把所有的类都做成bean。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-04
        • 1970-01-01
        • 2013-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-17
        相关资源
        最近更新 更多