Spring Framework coding hacks - by Mauricio Ferreira - Ronald James

Spring Framework coding hacks – by Mauricio Ferreira

Spring Framework coding hacks – by Mauricio Ferreira

I consider myself an enthusiast of the Spring Framework. I’ve been following and working with this platform since 2009. Just like any other Framework, you need to get used to it and learn the best practices to discover optimal ways of using it. In this article, I’ll highlight three Spring Framework coding hacks that could help you produce safer and better code following the Spring community best practices.

1. Constructor-based DI always

I want to start this article with a simple rule: always use constructor-based DI in your Spring beans. It can have a little more code to type, but that will save you lots of time in the long run.

There is an interesting post by O. Gierke that compares field Injection with constructor injection and evaluates its pros and cons. He starts the article mentioning that “field injection is evil,” because it creates an unsafe and more complicated code to test.

Just to recap, to inject another Spring Bean using field inject, it’s by placing the appropriate fields using @Autowired (or @Inject or @Resource) annotation. In the example below, the FooInject class has been injected by field injection in the FooComponent class.

People would typically argue that the field injection approach, which is probably the most common form of DI, reduces a lot of boilerplate code needed with setter or constructor injections. Although, the source code could be, like in the example above, “broken by default” as Gierke claims. That is right because it allows the client to create instances of the class in an invalid state.

As you might know, the constructor-based DI is achieved when the container invokes a class constructor with some arguments, each one expressing a dependency on other class. Now let’s try to rewrite the FooComponent class above using constructor-based DI to inject his dependencies instead.

I would always recommend explicit code over the implicit in any situation; it shouldn’t be different for the dependency injection.

Explicit forms of DI like the constructor-based one that we’ve seen enables you to code pure unit tests without using the DI framework and leaves your code less tied to the Spring Framework.

The only downside that the constructor-based approach brings is that is a little bit more code to write, but there is the Lombok approach to helps a lot to reduce this extra code.

2. Faster Boot

Launched in 2013, Spring Boot was created by Pivotal by solely listening to people debate about the issues that they encountered with the Spring framework.

When I first used Spring Boot at work, my first impression was mostly negative. I remember raising concerns about the many things that the Framework would be doing in the background without my acknowledgment. I wasn’t alone; some people claimed about Spring Boot things such as: “Spring is now so complex that it has its own framework” or “Spring Boot will never be used in production.”

Ok. Ok. Let me just say that using Spring Boot in production is not that different than any Java application. The principal goals of Spring Boot are: to provide a faster “getting started” experience, to offer a range of non-functional features (health check, metrics, etc.) and to be opinionated out of the box.

A typical concern that most of Spring Boot users have is related to application initialisation. It was designed to load everything on the application initialisation, and to try to fail as soon as possible. But it comes at a high price: the application takes a long time to “boot”, large memory usage, and could make quick tests potentially slow. Just to illustrate, a standard Spring Boot application usually takes about 2.5 seconds to initialise. it could get potentially more time-consuming when using more technologies with it such as Cloud libraries or Hibernate.

Fortunately, there are two ways to overcome this issue:

  • Lazy initialization

The first way would be using @Lazy initialisation annotation on your beans. A lazy- initialised is off by default and tells the IoC container to build a bean instance just when it is requested for the first time, rather than at the application startup.

In XML, this behavior is established by the lazy-init property on the <bean/> element; for instance:

Using Java config, the same beans would look like:

 

  • Spring Boot Devtools

Spring Boot Devtools helps to make application restarts much quicker. From Spring Boot 1.3 onwards, the devtoolsmodule aims to improve the development-time experience when working on Spring Boot applications.

And the feature that interests us to speed up the loading time is the Automatic Restart. Once the spring-boot-devtools module is included in the project configuration, any classpath file modifications will automatically trigger an application re-initialization. This simple technique will make your debugging and development faster and faster.

3. Handling exceptions right in a REST application

Exception Handling in Spring MVC is another topic that usually causes a lot of confusion. Most people are never too sure how to represent errors in a clean and an intuitive way.

An old post from P. Chapman in the Spring blog described the best practices when dealing with exceptions in the MVC framework. He highlights that are three solutions to handle exceptions with Spring for a REST API: per controller or globally or per exception.

  • At the controller level

This first solution uses the annotation @ExceptionHandler, and it should be added to each particular Controller class you wish to have specific exceptions handler method. This approach is illustrated in the code sample below:

  • Globally

Also at the controller level, is possible to have a global exception handler using
the @ControllerAdvice annotation. This annotation enables to have a global error handling component highlighted in the snippet below:

Per exception

Spring grants an interface called HandlerExceptionResolver that it’s possible to customise the default behavior of the global exception handler. This interface has different implementations to resolve the exception thrown during execution. Implementations such as:

 

SimpleMappingExceptionResolver

HandlerExceptionResolverComposite

ExceptionHandlerExceptionResolver

The example below illustrates how you can customise the exception handler method by extending AbstractHandlerExceptionResolver.

© Ronald James Ltd. 09824756. Q16 Business Exchange, Quorum Business Park, Newcastle upon Tyne, Tyne and Wear, NE12 8BX, United Kingdom. Website by Outlines Design.