在Spring单例(singleton)Bean中是否应该使用static呢?

huangapple go评论80阅读模式
英文:

Should I use static at all in spring singleton beans

问题

根据我刚刚阅读的内容,默认情况下,我创建的 Spring Beans 是单例的。目前我在使用 static 关键字来定义我的日志记录器、重复使用的变量以及一些我希望只存在一次的列表。

但由于所有的 Bean 都是单例的,我在考虑是否应该从所有地方移除 static

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 上下文中是否应该使用 static?如果是,为什么?

英文:

As I just read, by default my created spring beans are Singletons. I'm currently using the static keyword for my Loggers, reused variables, and some Lists that I want to exist only once.

But because alls beans are singletons I'm thinking about just removing static from everything.

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

to

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

My question is, should I use "static" at all within the spring context? If yes, why?

答案1

得分: 4

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

拥有一个静态final的日志记录器是完全可以的。日志记录器是线程安全的,并且设计成可以以这种方式使用。

拥有静态final常量是可以的。

除了日志记录器之外,任何不是不可变的静态内容都应该避免使用。

此外,不要使用实例变量来保存会话状态(与服务调用者执行的操作相关的状态),因为其他调用者可以访问并更改该状态。

如果您正在使用实例变量或静态变量进行缓存,请摒弃它们,并配置一个缓存管理器。

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

英文:

Spring is designed so that for the vast majority of cases you can avoid static fields.

Having a logger that is static final is perfectly ok. Loggers are threadsafe and are designed to be used this way.

Having static final constants is ok.

Other than loggers, anything static that is not immutable should be avoided.

Also do not use instance variables for conversational state (state related to actions performed by callers of the service), because other callers can access and change that state.

If you are using instance or static variables to cache, get rid of them and configure a cache manager instead.

If your code is storing configuration data in static fields, make them instance fields and use spring to read the config data in.

答案2

得分: 2

在类内部使用静态记录器通常是有意义的,如果它记录到同一个文件或输出流(例如 System.out),无论哪个实例记录了某些内容。关于您代码片段中的队列是否应该是静态的取决于它的使用情况,如果没有更多细节,无法回答这个问题。

英文:

Using a static logger within a class generally makes sense if it is logging to the same file or output stream (e.g. System.out), regardless of which instance logs something. Whether the queue in your code snippit should be static or not depends on its use and cannot be answered without more details.

答案3

得分: 1

很好的问题。在我看来,如果您的业务场景始终保持在同一个 Spring 上下文中,您不应该使用静态变量。原因是 Spring Bean 在一个 Spring 上下文中是单例的。但是在不同的 Spring 上下文中,Bean 会有不同的实例。下面是示范代码:

// 第一个 Spring Bean 上下文
ApplicationContext context1 = new FileSystemXmlApplicationContext("classpath:/ApplicationContext.xml");
Biz b1 = context1.getBean("myBean", Biz.class);

// 第二个 Spring Bean 上下文
ApplicationContext context2 = new FileSystemXmlApplicationContext("classpath:/ApplicationContext.xml");
Biz b2 = context2.getBean("myBean", Biz.class);

// 结果为 false,因为创建了两个 Biz 实例
System.out.println(b1 == b2);

但是静态变量在一个 JVM 中只有一个实例。因此,为了性能和稳健性,您应该更经常地使用静态变量。换句话说,并不是程序中的所有类都可以作为 Bean。

英文:

Good question. In my opinion, If you business scenario stay always in same spring context, you should not use static. The reason is that spring bean is single in one spring context。But bean has different instance in different spring context. The below is sample code:

//  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);

But static variable has one instance in one JVM. So for performance and robust,you should use static more often. In another word, you can not make all class as bean in a program.

huangapple
  • 本文由 发表于 2020年10月10日 09:05:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/64289009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定