Skip to main content

POV: Prototype injection into Spring singleton, an antipattern. Opinions invited

Today someone asked me, how would Spring behave with respect to object instantiation if a Prototype bean was injected into a Singleton.

This took me by surprise and the reaction was "Why in the world would we even do that?". Do we ever have instance level objects in Singletons, that might be prone to change, as that is what prototype beans would be for? No we do not, then why would we do that in Spring.

The very intent of Singleton is to embody the logic of our application code, that has no state. It makes sense for Prototype beans, to have Singleton beans injected in them, for doing work.
But the other way round, not so much.

However, I went through the spring documentation and to my surprise there was a section(3.5.3) dedicated to Prototype beans injected into Singleton beans. And as expected, though it does not fail, such a dependency injection just results in a fixed instance of the Prototype bean to be injected into the Singleton. That instance does not change through the life of the container. Essentially, a singleton instance. However, if we have three Singletons with same Prototype bean injected, it would result in three separate Prototype instance to be created and injected into each.

This makes perfect sense. Singletons are meant for multi-threaded access of logic and if the prototype injection resulted into different objects, the entire thing will go for a toss.

So what's the practical application? Even if we need different instances of a bean to be injected into our three Singletons, with different initial data, that does not require Prototype bean scope. Remember, Spring creates Singleton instance per bean definition.

So if you know any real scenario where this might be applicable, please do comment below. But for now, let's deem it as an anti-pattern. This is something Spring should shun from documentation unless that's there with the explicit intent to confuse.

Extending this to Session scope beans.

Shunning my inherent hatred towards Spring web, let's dwell into this concept. Some may consider the standard use case of session scoped beans injected into Controller or Service beans as analogous to prototype beans injected into Singleton beans.
But nothing is far from truth. Though, the session scoped bean may look like injected into the Singleton Controller or Service, it is not. What is injected is an aop-proxy, which is actually a single instance object, which fetches the corresponding session scope bean instance and returns it. This is more analogous to lookup-method injection, into singletons.




Comments

Popular posts from this blog

Using JNDI managed JMS objects with Apache CAMEL

Apache CAMEL uses Spring JMS to work with JMS Queues or Topics. Evidently, we will need Spring to configure and use JMS capabilities provided by CAMEL. Details about how to implement JMS based routes using Apache CAMEL can be found in the CAMEL documentation. However, the documentation leaves a lot to be figured out. In a typical Java EE container, it is usually a good idea to abstract the underlying JMS resources by using JNDI. We can use the below configuration to achieve that. This configuration is tested in Websphere environment, but should work in any JEE container. Create a JMS queue connection factory in the JNDI registry. CAMEL configuration will be able to use only one queue connection factory, even if we have more than one. Create one or more JMS queue or topics, in the JNDI registry, as required. The above two steps are related to generic JNDI configuration for JMS resources. Now we come to the setup required for making these JMS resources work with CAMEL rout...

Catch hold of that Exception and hide that stacktrace!!!

E xceptions happen!!! Rules are to be followed, too. Time and again, Java developers are told the golden rule to catch specific exceptions and not to catch the generic Exception. The thought process behind that is, applications should not catch runtime exceptions. This is apt as runtime exceptions are an indicator of "bugs" in the code. However, blindly following rules, as always, can have unexpected consequences. If you are developing services that are to be exposed over the wire, it is always a good idea to break this rule and "catch that Exception". Instead, follow the below principles: Service methods should implement a generic Exception block, along with catching declared exceptions, thrown from inner layers of the code.  If needed, the service can throw another exception back to the client. What's important is that we create a new Exception instance to be thrown, along with relevant message for the client. The service can log stacktrace for the E...

Container ready spring boot application

Spring boot applications are now ubiquitous. The usual way to build one is to create an uber jar. At the same time, Docker allows us to build self reliant containers which are unaffected by the underlying server architecture or neighboring applications or their dependencies. Spring boot applications can also run in docker containers.  However running an uber jar inside a container fails to satisfy an important goal. That of high speed build and deployment. An uber jar is a heavy weight entity. That will make docker image heavy and slow to build. Here's a step by step solution, which leverages docker layer caching feature for faster builds with all spring boot goodness. We will use Maven to build a deployment structure for our docker image that allows fast deployments. Step 1: Create a spring boot application with only the SpringBootApplication and Configuration classes, such as one for REST configuration package scanning, one for JPA etc. Most often this wil...