Utility class in Spring application - should I use static methods or not?
Asked Answered
D

5

84

Let's say I have a utility class DateUtil (see below). To use this method a caller method uses DateUtils.getDateAsString(aDate). Would it be better to remove the static modifier and make DateUtil a spring bean (see DateUtilsBean) and inject it into calling classes or just leave it as is?

One disadvantage I can see with using static is issues around mocking, see How to mock with static methods?

public class DateUtils {

    public static String getDateAsString(Date date) {       
        String retValue =  "" // do something here using date parameter
        return retValue;
    }
}

Spring Bean version

@Component
public class DateUtilsBean {

    public String getDateAsString(Date date) {      
        String retValue =  "" // do something here using date parameter
        return retValue;
    }
}
Dungdungan answered 1/9, 2011 at 13:2 Comment(0)
P
54

I don't think so. A DateUtils class sounds like a pure utility class that doesn't have any side effects but just processes input parameters. That kind of functionality may as well remain in a static method. I don't think it's very likely that you'll want to mock date helper methods.

Pindling answered 1/9, 2011 at 13:6 Comment(5)
Agreed. Just because anything could be wired as a Spring bean doesn't mean everything should be wired as a Spring bean.Anthology
what if the static method reads a configuration file that drives my application? that is likely that I want to mock that behavior. Just think of it: you want to do functional testing but you don't want to become a "configuration factory". if it would be a singleton then I can more easily mock that method and drive my test from code. However it's possible with PowerMock to mock static methods too.Katzen
It could be over-engineering, but making it a bean that can be injected makes it easier to unit-test dependent classes. It would make it even easier to test if it had implemented an interface.Borrero
An important use case is time. Consider using Java 8's Clock as a bean to avoid flaky tests related to time.Worst
@DavidW true, but that Clock was specifically designed for that purpose. I've used it when editing other people's code, but I'd still prefer to make my methods idempotent, so I'd pass in Dates from the outside.Pindling
I
32

I agree with Sean Patrick Floyd.

This is my criterion: if the methods of the class do things only over the parameters they receive, with no external dependencies (database, file system, user config, other objects/beans, etc.), then I would do it with static methods, usually in a final class with a private constructor.

Otherwise, I would implement it using a Spring bean.

So, in the case that you raise, according to this criterion, I would write a class with static methods.

Regards.

Impulsive answered 26/2, 2016 at 9:47 Comment(0)
L
19

It would be better to declare it as a Spring bean because the life cycle of it is then managed by Spring, and you can eventually inject dependencies, pool the object, as well as test it in a proper way, not to talk that you could use it as a regular object and pass it as parameter, redefine the method in subclasses... etc.

In short, yes it would be a better design in most cases. Nevertheless, in a case as simple as the exposed, it doesn't do a great difference.

Lifeless answered 1/9, 2011 at 13:9 Comment(0)
I
4

While most people here support the idea to have Util classes with static methods, instead of Spring beans, I would oppose.

  1. Dependency injection made for reason. This is the tool to replace any of Spring Bean with different implementations in case of different context. Most common is development and test context difference. But we also can have a new context in the future (production, different data transfer protocol, different database implementation etc). In this case an interface implementation bean, injected by Spring would make life much easier.

Doing the opposite - using the util classes with static methods is the well known design problem called Tight Coupling and it leads to Code Fragility.

  1. Consider a situation where you have an utility class with static methods. At some point you need to add an injected dependency as new feature requested. All of a sudden it is not a Util but UtilBean now. So instead of adding a method to your original Util, you have to rename it and refactor all code calling it. Refactoring is cheap, right? Not so fast if you are building a library which is used in other applications and you do not have control over them. And guess what? How do you know your code today is not a compiled library dependency tomorrow?

All right, we worked hard, renamed util to bean and all is great. But we got a new feature request, and next we have to remove the method from bean. Now it does not have dependency and we need to rename bean to util back.

  1. If developers use Spring they often follow MVC architecture design. Where would be the Util class in this case? It sounds like a Service, but it appears to be something different and likely would have a separate package. Not so nice.

Bottom line => With Spring use Beans and don't mess around Utility classes with static methods. I would say it is valid to consider with any application where dependency injection is used.

Here my article regarding the problem https://medium.com/@pavlomorozov78/static-methods-in-spring-utility-classes-9994ae6aa949

Impaste answered 22/5, 2023 at 9:16 Comment(0)
O
2

A good answer in this comment Should I use static at all in spring singleton beans

static variable has one instance in one JVM. Singleton exists per spring context. If your application has only one context, they do the same job.

But do not mix them together. In some old projects, I see some not-pure utility class using some spring bean via ApplicationContext. It is very hard to write test case for it.

Otey answered 2/12, 2022 at 18:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.