DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Using Render Log Streams to Log to Papertrail
  • Incident Response Guide
  • Building and Deploying Microservices With Spring Boot and Docker
  • Demystifying SPF Record Limitations

Trending

  • Using Render Log Streams to Log to Papertrail
  • Incident Response Guide
  • Building and Deploying Microservices With Spring Boot and Docker
  • Demystifying SPF Record Limitations
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Spring, IoC Containers, and Static Code: Design Principles

Spring, IoC Containers, and Static Code: Design Principles

Here, learn about the inversion of control patterns, static code within an IoC framework, and wiring utility methods in static code inside the IoC framework.

Gregory Anne user avatar by
Gregory Anne
·
Updated Jun. 24, 22 · Analysis
Like (3)
Save
Tweet
Share
6.72K Views

Join the DZone community and get the full member experience.

Join For Free

In this article, I would like to discuss the inversion of control patterns, static code (can be legacy or newly created) within an IoC framework like spring, and the issue of wiring utility methods in static code inside the IoC framework.

Static Methods

For example, we have an HttpUtils class with inside a bunch of static methods. Should we remove the static keyword and annotate the class with a Spring stereotype, which would immediately turn it into a Spring Singleton?

In Java, the static keyword indicates that a member or method belongs to the type itself rather than an instance of that type. This means that only one instance of this static member is created and that it is shared between all instances of the class. If it is a static method within an IoC framework, this means that the way the method is run is unique for all the usages of this class and this method.

In this case, there are 3 possibilities:

  1. The method does not modify context data (data being handled by the application). So we can consider that despite its static character, it is thread-safe.
  2. The method modifies context data, so it is thread-unsafe.
  3. The method modifies context data, but it is thread-safe because it is "synchronized" (one execution at a time), which can severely penalize performance.

Static methods in Java are provided as is at build time. This is why it is never possible to overload them. As a result, abstract methods cannot be static, and they can never access class or context values without being passed as an argument (cannot access this or super).

So does static code apply to "Utils" classes? Yes, since we are in case 1, there will be no modified data from the context, the input is translated into output, and as a general rule, this type of class can be exported regardless of the context. However, if it is exportable, shouldn't this code be then squarely in a lib available to all projects? Yes, cross-functional teams would be happy to receive regular contributions from teams that have thought of making utility codes available to everyone that doesn't need context.

Does static code apply to anything else? Not if there is a better thing to do.

Scopes Usable on Spring

Scope
Description
singleton This scopes the bean definition to a single instance per Spring IoC container (default).
prototype This scopes a single bean definition to have any number of object instances.
request This scopes a bean definition to an HTTP request. Only valid in the context of a web-aware Spring ApplicationContext.
session This scopes a bean definition to an HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.
global-session This scopes a bean definition to a global HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.

Singletons

If a scope is set to Singleton, the SpringIoC container creates exactly one instance of the object defined by that bean definition. This single instance is stored in a cache of these Singleton beans, and all subsequent requests and references for this bean return the object in the cache.

The engine manages any cache, an expiration, and regeneration of the bean if it is taken out of the stock. A cache exit is possible if the bean has no more or no state.

For example, when calling an httpsUtils.callUrl(), the container must decide if it wants to reuse an already instantiated bean or create a new one. How does the container decide? When registering the bean httpUtils in the container (on the framework), it is possible to indicate to this container how we would like it to behave. Also, the first instance can be created at the start of the application or the first call on the bean. That said, bean callers don't have to know about the bean's life cycle; they call httpUtils.callUrl().

This is the optimal way to provide class methods in an application that contains a quantity of classes and a quantity of methods per class.

We, therefore, have a first (global) performance argument to transform all the static methods into Singletons in order to benefit from the SpringIoC cache. Accessing a static method is faster in theory because the JVM doesn't need to look up the function before executing it, but in practice, most JDKs optimize instance method calls. That said, when it comes to performance, the most common cause is poor design. If static code is faster, then we could code the entire application in static code; why even declare classes and methods following the IoC pattern when that pattern and static code can do the same job well that they are constructed differently?

If we take again the example of the HttpUtils class, the principle of using static code is that I can directly access the callUrl() method from the class; we combine the definition of callUrl() and its implementation in the same place. IoC strives to separate this kind of detail, so instead, we define a method outside of it in an interface. This allows, for example, to decline this interface with several implementations. An interface implementation for HttpUtils would become a configuration of HttpUtils. Note that classes using HttpUtils will have no idea of the execution scope of callUrl() since the scopes used in the framework also depend on a configuration.

In summary, IoC and static are generally at odds. IoC promotes change while static, by definition, prevents it. Inject your dependencies according to the framework, and you will see that you can completely dispense with using static features.

Security

One more argument: according to Sonar, all members of a Spring bean should be injected.

 
Vulnerability: Critical

spring

owasp

Spring @Component, @Controller, @Service, and @Repository classes are singletons by default, meaning only one instance of the class is ever instantiated in the application. Typically such a class might have a few static members, such as a logger, but all non-static members should be managed by Spring. That is, they should have one of these annotations: @Resource, @Inject, @Autowired or @Value.

Having non-injected members in one of these classes could indicate an attempt to manage state. Because they are Singletons, such an attempt is almost guaranteed to eventually expose data from User1's session to User2.


This rule raises an issue when a Singleton @Component, @Controller, @Service, or @Repository, not annotated with @ConfigurationProperties, has non-static members that are not annotated with one of:

  • org.springframework.beans.factory.annotation.Autowired
  • org.springframework.beans.factory.annotation.Value
  • javax.annotation.Inject
  • javax.annotation.Resource

Non-compliant code:

 
@Controller
public class HelloWorld {
  private String name = null;
  @RequestMapping("/greet", method = GET)
  public String greet(String greetee) {
    if (greete != null) {
      this.name = greetee;
    }
    return "Hello " + this.name; // if greetee is null, you see the previous user's data
  }

}


String is a class. Any class that is concerned, including those that contain static methods that would be called within a Spring bean.

Container Design Spring Framework Bean (software)

Opinions expressed by DZone contributors are their own.

Trending

  • Using Render Log Streams to Log to Papertrail
  • Incident Response Guide
  • Building and Deploying Microservices With Spring Boot and Docker
  • Demystifying SPF Record Limitations

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: