Education logo

How to Implement Good Coding Standards in Spring Boot

Keeping up with Industry Best Practices and Framework Guidelines

By Kishore KarnatakapuPublished 10 months ago 5 min read
2

Spring Boot is a widely used and very popular enterprise-level high-performance framework. Here are some best practices and a few tips you can use to improve your Spring Boot application and make it more efficient. This article will be a little longer, and it will take some time to completely read the article.

Proper packaging style

  • Proper packaging will help to understand the code and the flow of the application easily.
  • You can structure your application with meaningful packaging.
  • You can include all your controllers into a separate package, services in a separate package, util classes into a separate package…etc. This style is very convenient in small-size microservices.
  • If you are working on a huge code base, a feature-based approach can be used. You can decide on your requirement.

Use Design Patterns

  • Design patterns play a crucial role in software engineering by providing proven solutions to recurring design problems. They serve as reusable templates that help improve code structure, maintainability, and scalability.
  • But you must identify the place where you can use them.

Use Spring Boot Starters

  • This is a cool feature of Spring Boot, we can very easily use starter dependencies without adding single dependencies one by one. These starter dependencies are already bundled with the required dependencies.
  • For example, if we add spring-boot-starter-web dependency, by default it is bundled with jackson, spring-core, spring-mvc, and spring-boot-starter-tomcat dependencies.
  • So we don't need to care about adding dependencies separately and also it helps us to avoid version mismatches.
  • Use proper versions of the dependencies
  • It is always recommended to use the latest stable GA versions.
  • Sometimes it may vary with the Java version, server versions, the type of the application…etc.
  • Do not use different versions of the same package and always use <properties> to specify the version if there are multiple dependencies.

Use Lombok

  • As a Java developer, you have probably heard of the Lombok project.
  • Lombok is a Java library that can be used to reduce your codes and allow you to write clean code using its annotations.
  • For example, you may use plenty of lines for getters and setters in some classes like entities, request/response objects, dtos…etc.
  • But if you use Lombok, it is just one line, you can use @Data, @Getter or @Setter as per your requirement.
  • You can use Lombok logger annotations as well. @Slf4j is recommended.

Use constructor injection with Lombok

When we talk about dependency injection, there are two types.

One is "constructor injection" and the other is "setter injection". Apart from that, you can also use "field injection" using the very popular @Autowired annotation.

But we highly recommend using Constructor injection over other types. Because it allows the application to initialize all required dependencies at the initialization time. This is very useful for unit testing.

The important thing is, that we can use the @RequiredArgsConstructor annotation by Lombok to use constructor injection.

Use slf4j Logging

  • Logging is very important, if a problem occurs while your application is in production, logging is the only way to find out the root cause. Therefore, you should think carefully before adding loggers, log message types, logger levels, and logger messages.
  • Do not use System.out.print()
  • Slf4j is recommended to use along with logback which is the default logging framework in Spring Boot.
  • Always use slf4j { } and avoid using String interpolation in logger messages. Because string interpolation consumes more memory.
  • You can use Lombok @Slf4j annotation to create a logger very easily.
  • If you are in a micro-services environment, you can use the ELK stack.

Use Controllers only for routing

  • Controllers are dedicated to routing, it is stateless and singleton.
  • The DispatcherServlet will check the @RequestMapping on Controllers
  • Controllers are the ultimate target of requests, then requests will be handed over to the service layer and processed by the service layer.
  • The business logic should not be in the controllers, use Services for business logic
  • The complete business logic goes here with validations, caching…etc.
  • Services communicate with the persistence layer and receive the results.
  • Services are also singleton.

Avoid NullPointerException

  • To avoid NullPointerException you can use Optional from java.util package.
  • You can also use null-safe libraries. Ex: Apache Commons StringUtils
  • Call equals() and equalsIgnoreCase() methods on known objects.
  • Use valueOf() over toString()
  • Use IDE-based @NotNull and @Nullable annotations.

Use best practices for the Collection Framework

  • Use appropriate collection for your data set.
  • Use forEach with Java 8 features and avoid using legacy for loops.
  • Use interface type instead of the implementation.
  • Use isEmpty() over size() for better readability.
  • Do not return null values, you can return an empty collection.
  • If you are using objects as data to be stored in a hash-based collection, you should override equals() and hashCode() methods.

Use Pagination

  • This will improve the performance of the application.
  • If you're using Spring Data JPA, the PagingAndSortingRepository makes using pagination very easy and with little effort.

Use Caching

  • Caching is another important factor when talking about application performance.
  • By default Spring Boot provides caching with ConcurrentHashMap and you can achieve this by @EnableCaching annotation.
  • If you are not satisfied with default caching, you can use Redis, Hazelcast, or any other distributed caching implementations.
  • Redis and Hazelcast are in-memory caching methods. You also can use database cache implementations as well.

Use custom exception handler with global exception handling

  • This is very important when working with large enterprise-level applications.
  • Apart from the general exceptions, we may have some scenarios to identify some specific error cases.
  • Exception adviser can be created with @ControllerAdvice and we can create separate exceptions with meaningful details.
  • It will make it much easier to identify and debug errors in the future

    Use custom response object

  • A custom response object can be used to return an object with some specific data with the requirements like HTTP status code, API code, message…etc.
  • We can use the builder design pattern to create a custom response object with custom attributes.

Remove unnecessary codes, variables, methods, and classes

  • Unused variable declarations will acquire some memory.
  • Remove unused methods, classes…etc because it will impact the performance of the application.
  • Try to avoid nested loops. You can use maps instead.
  • Use meaningful words for classes, methods, functions, variables, and other attributes
  • Always use proper meaningful and searchable naming conventions with proper case.
  • Usually, we use nouns or short phrases when declaring classes, variables, and constants. Ex: String firstName, const isValid
  • You can use verbs and short phrases with adjectives for functions and methods. Ex: readFile(), sendData()
  • Avoid using abbreviating variable names and intention revealing names. Ex: int i; String getExUsr;

Use proper case for declarations

  • There are many different cases like UPPERCASE, lowercase, camelCase, PascalCase, snake_case, SCREAMING_SNAKE_CASE, kebab-case…etc.
  • But we need to identify which case is dedicated to which variable.

Usually, I follow,

  • Classes  -  PascalCase
  • Methods & Variables  -  camelCase
  • Constants  -  SCREAMING_SNAKE_CASE
  • DB-related fields -   snake_case

Be simple

  • Always try to write simple, readable codes.
  • The same simple logic can be implemented using different ways, but it is difficult to understand if it is not readable or understandable.
  • Sometimes complex logic consumes more memory.

Use SonarLint

  • This is very useful for identifying small bugs and best practices to avoid unnecessary bugs and code quality issues.
  • You can install the plugin into your favorite IDE.

teacherstudentdegreecourses
2

About the Creator

Kishore Karnatakapu

I'm a passionate software engineer with a good background in full-stack development and expertise in technologies like Java,Spring Boot,Microservices & Angular.Follow for intriguing articles on software engineering & latest industry trends

Reader insights

Be the first to share your insights about this piece.

How does it work?

Add your insights

Comments (1)

Sign in to comment
  • everyday entertainment10 months ago

    Nice information

Find us on social media

Miscellaneous links

  • Explore
  • Contact
  • Privacy Policy
  • Terms of Use
  • Support

© 2024 Creatd, Inc. All Rights Reserved.