3

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?

3 Answers3

4

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.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • Okay, so I'll keep those static. I think the application I'm writing is not big enough to require a cache manager. I'm currently storing data inside instance ArrayLists. I'm not manipulating those from other classes so please correct me if I'm wrong but that should be fine. – Faye Schipper Oct 10 '20 at 01:43
  • @Jan: Letting spring handle the cache outside your code has the advantage that you can modify how the caching works without changing your code. Homegrown caching code is usually inflexible and brittle. Might be worth giving it a try. – Nathan Hughes Oct 10 '20 at 01:46
  • Yea, you're right. Although in my business case I'm rather "storing" my objects instead of "caching" them to reuse them later. (If that's the right understanding of caching here.) I just don't put them in the database because they're allowed to be lost in case of a program shutdown. But I think I'm getting too specific here. Thank you for the answer! – Faye Schipper Oct 10 '20 at 01:58
  • This would be a bit clearer by explicitly calling out static _state_ as the problem (as the logger is not state). – chrylis -cautiouslyoptimistic- Oct 10 '20 at 02:41
  • @chrylis-cautiouslyoptimistic- Yea, you're right. The original answer fits anyway though. – Faye Schipper Oct 10 '20 at 02:52
  • @chrylis: that would make this more focused. But conversational instance state is problematic too, as well as static state. Also, the logger isn’t exactly stateless, it can maintain its own state. Though it is kept apart from the rest of the application. I figured I’d get nitpicked if I called the logger stateless. – Nathan Hughes Oct 10 '20 at 02:57
2

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.

Pieter12345
  • 1,713
  • 1
  • 11
  • 18
1

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.

jacky-neo
  • 763
  • 4
  • 7
  • Why does a spring boot application need more than one context? – Abe Dec 02 '22 at 17:24
  • it depends on your business requirements. for example, please see [here](https://www.baeldung.com/spring-boot-context-hierarchy) a spring-boot application provides two port to access different service. – jacky-neo Dec 03 '22 at 03:10