Spring prototype scope - Use Cases? - java

I have clear understanding of the various scopes of Spring beans. But I am looking for some use cases of prototype scope of a bean in enterprise tier projects. It would be great if you can share some real life use cases of the prototype scope (not the request scope).

As someone who previously worked at SpringSource and have talked to the developers on this topic. Here is my take. Prototype is great for testing things out, hence the name prototype and not create new or something more description of creating a new instance of the bean each and every time you request it from the Spring container.
I have also found in my use over the years that I cannot think of any other place where prototype makes sense in any real-world production application. If your object holds state, it typically shouldn't be a Spring bean. I have found in all the applications I have worked on that all beans are Services, Repositories, and Singleton non state holding objects where I need to add features like Transactionality, JPA, JMS and the likes that give us the enterprise features that POJOs don't have.
The objects in my system that hold state are my Entities and View DTOs maybe, or other things that just make no sense to be a Spring Bean. So therefore in my applications in production there hasn't been a single "prototype" bean.

I used prototype beans to declare configured form elements (a textbox configured to validate names, e-mail addresses for example) and get "living" instances of them for every form being created in my webapp. The details are not important, only the principle, that I would summarize this way:
There is a class that has many config parameters
You need to create instances of it with a set of predefined configuration (fancy1, fancy2, stc.)
Think of the applicationContext.getBean("myBeanConfiguredFancy1") as a kind of factory method that creates the instance as preconfigured in the xml

I have used prototype mostly in conjunction with spring lookup-method. My application is a game server that needs to decode incoming bytes at tcp port. Consider the following bean definition
<bean id="channelBufferProtocol" class="org.menacheri.protocols.impl.ChannelBufferProtocol">
<lookup-method name="createLengthBasedFrameDecoder" bean="lengthFieldBasedFrameDecoder"/>
<property name="eventDecoder" ref="eventDecoder"></property>
<property name="lengthFieldPrepender" ref="lengthFieldPrepender"></property>
<property name="eventEncoder" ref="eventEncoder"></property>
</bean>
Inside the protocol implementation class, I have the following code to create the frame decoder pipeline.addLast("lengthDecoder", createLengthBasedFrameDecoder()); When this method is invoked, spring will create a new frame decoder instance and return it.
The bean returned by bean="lengthFieldBasedFrameDecoder" needs to be of scope prototype, since it is a stateful bean in my app.
Note: A protocol is nothing but a specific set of decoders and encoders chained together. "Chain of responsibility" design pattern.

We can use prototype scope in case of model classes(also called as Entities in hibernate) as application need different instances of model class for each thread/request.

Related

Dependency injection and multiple instances

I am using spring framework for dependency injection, but I simply cannot find out, if I am using it right. Imagine this case - it is not real, but just to explain my problem. I have a spring boot application which connects with websocket to some endpoints. I have a class which has all available methods for this client, stores all needed data for client etc., let's say Client. Then I have a static list which holds all connected clients List<Client>. I need that the Client class is Spring managed bean, as I need to use #Service and all other spring features (#Value, #Async) etc.
The problem is, spring beans are singletons right? How can I instantiate then object from a class which should be spring managed but on the other hand there should be multiple instances of this class?? I cannot use new right?`
It isn't necessarily true that spring-created objects are singletons; this is merely the default. Spring supports a variety of different options for determining when a new object is created versus an old one being recycled. You should look at the documentation for the "scope" attribute and determine what is most appropriate for your application.
Alternatively, you can create the object yourself using new and then request Spring to configure it for you using the technique described at http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable

What does it mean to "proxy a bean"?

At work and online I keep hearing the term "proxy" with respect to enterprise Java development. For example, metrics-spring uses this phrase:
This module does the following things:
Creates metrics and proxies beans which contain methods annotated with
#Timed, #Metered, #ExceptionMetered, and #Counted [emphasis mine]
I'm unfamiliar with a lot of the language in the Java ecosystem of frameworks and libraries. I feel like I have a good understanding of what a bean is, but I'm still not clear about how one would proxy a bean.
What does it mean to proxy a bean?
Typically, you have a bean like
Bean bean = new Bean(); // actually created by the context
With this, you can do anything that the Bean class declares as behavior (invoke its methods).
There are times where it would be nice if you could, for example, track how long a method invocation takes.
You could do
long start = .. // get start time
bean.invoke();
long end = .. // get end time
// end - start
But doing this for each method invocation sucks. So, instead, patterns, architectures, and styles like Aspect Oriented Programming exist.
Instead of the Bean above, you'd have
Bean bean = new TimingBean(new Bean()); // again done by the context
where the TimingBean is a proxy type that extends and implements all the types that Bean extends and implements. For all intents and purposes it is a Bean, but it adds a bunch of additional behavior before delegating each invocation to the Bean object. In this case, it would track how long each of Bean's method's took to execute.
Basic Spring uses JDK proxies and CGLIB proxies. Here are some differences between them.
It uses this for its scheduling and asynchronous invocations. It uses it for transactional support with databases. It uses it for caching. It even uses it for its Java based container configuration.
Proxying means that your client code thinks it's talking to one bean, but a proxy is really doing the listening and responding.
This has been true since early distributed client/server computing models like CORBA. A client would interact with an interface type as if it existed in their memory space, but they were really talking to a proxy that would handle all the messy details around marshalling request data into a request, communicating over the network to the remote object running on a server, and unmarshalling the response back to the client.
Spring uses this model for remoting. It also forms the basis for its aspect oriented programming model. Your code thinks it's dealing with a particular interface; Spring can weave in advice before, after, or around that instance and perform cross cutting operations like logging, transaction management, etc. on your behalf.
Some frameworks rely on a mechanism called instrumentation, which in short means to build a proxy of a given compiled bytecode, adding some code to it in some places we judge useful. This would implement many kinds of tasks, between them for example, adding a kind of profiling to a spring bean, as this library claims to do.
The Spring engine returns heavily instrumented proxies of every managed bean it offers - this way, you can use Spring declarative transaction handling, for instance. You would write "naive" daos without an actual connection handling, and "naive" service classes using the daos without an actual transaction handling - the instrumented proxies will include the boilerplate code with the connection instantiation, commits, rollbacks...
I hope this is of any help

How to stop Wicket creating multiple instances of Guice-injected singletons?

I'm a new Guice user, having been a long-time user of Spring IoC. I have a number of #Singleton classes for my service tier, which I understand is roughly equivalent to Spring's default bean scope.
However, when I am using #Inject in my Wicket pages a CGLib proxy of the target objects is created each time the page is constructed, thus creating new instances of my supposed-singletons.
Note that I'm injecting concrete classes, not interfaces.
How can I use #Inject and retrieve the single singleton instance of my Guice-injected objects?
Updated: Solution as per Sven's accepted answer
Inject interfaces in Wicket components rather than concrete classes. Despite much discussion on the subject in the linked thread, this appear to be the only practical solution.
The following issue gives some background:
https://issues.apache.org/jira/browse/WICKET-1130

Why does Spring initialize the instances as singletons? What are some reasons that influenced their decision to handle initialization this way?

I don't understand the decision for why the Spring Framework is designed by default to return instances that are a singleton. So the same object is passed around when calling the application context. What are some reasons that influenced spring's decision to handle bean initialization this way? What are some bad things that can happen if all beans were initialized as prototypes?
Thank you in advance.
I think that Spring documents explain this point very well. Shortly the reason is that if your bean is stateless your do not need more than one instance. Since most beans are stateless "singleton" is a default scope. You can however change this. There are other scopes, e.g. session, request etc.
If for example you implement web store and need curt implementation session scope is what you need. If however you support special parameters that are sent for each request separately you probably want to use request scope for this purpose.
But beans that access database, perform authentication, send email or SMS, do other business logic can and should be implemented using singleton scope.

Custom spring scopes?

Anyone know of any other custom spring scopes than Servlet Context Scope and ThreadScope ?
If you've made some closed-source custom scope I'd really also be interested in hearing what it does and how it worked out for you. (I'd imagine someone would make a WindowScope in a desktop app ?)
I'm open to all use cases, I'm looking to expand my horizon here.
We implemented our own custom Spring scope. A lot of our code works at a relatively low level, close to the database, and we maintain a conceptual level on top of that with its own object model of data sources, links, attributes etc.
Anyway, a lot of beans require a so-called StorageDictionary (an encapsulation of this object graph) to do their work. When we make non-trivial changes to the object graph, the dictionary sometimes needs to be blown away and recreated. Consequently, we implemented a custom scope for objects that were dictionary scoped, and part of the invalidation of a given dictionary involves clearing this custom scope. This lets Spring handle a nice form of automatic caching for these objects. You get the same object back every time up until the dictionary is invalidated, at which point you get a new object.
This helps not only with consistency but also allows the objects themselves to cache references to entities within the dictionary, safe within the knowledge that the cache will be valid for as long as they themselves are retrievable by Spring. This in turn lets us build these as immutable objects (so long as they can be wired via constructor injection), which is a very good thing to do anyway wherever possible.
This technique won't work everywhere and does depend heavily on the characteristics of the software (e.g. if the dictionary was modified regularly this would be horribly inefficient, and if it was updated never this would be unnecessary and slightly less efficient than direct access). However, it has definitely helped us pass off this management of lifecycle to Spring in a way that is conceptually straightforward and in my opinion quite elegant.
In my company we've created two custom scopes, one that will use Thread or Request and another that will use either Thread or Session. The idea is that a single scope can be used for scoped beans without having to change configuration based on the execution environment (JUnit or Servlet container). This also really comes in handy for when you run items in Quartz and no longer have a Request or Session scope available.
Background:
I work on a single web app that runs 4 different web sites under the same servlet context. Each site has its own domain name, e.g. www.examplesite1.com, www.examplesite2.com, etc.
Problem:
Sites sometimes require their own customised instance of a bean from the app context (usually for customised display of messages or formatting of objects).
For example, say sites 1 and 2 both use the "standardDateFormatter" bean, site 3 uses the "usDateFormatter" bean and site 4 uses the "ukDateFormatter" bean.
Solution:
I'm planning on using a "site" scope.
We have a Site enum like this:
enum Site {
SITE1, SITE2, SITE3, SITE4;
}
Then we have a filter that stores one of these Site values in the request's thread using a ThreadLocal. This is the site scope's "conversation id".
Then in the app context there'd be a bean named "dateFormatter", with 'scope="site"'. Then, wherever we want to use a date formatter, the correct one for the user's current site will be used.
Added later:
Sample code here:
http://github.com/eliotsykes/spring-site-scope
Oracle Coherence has implemented a datagrid scope for Spring beans. To sum it up:
A Data Grid Bean is a proxy to a
java.io.Serializable Bean instance
that is stored in a non-expiring
Coherence Distributed Cache (called
near-datagridbeans).
Never used them myself but they seem cool.
Apache Orchestra provides SpringConversationScope.
In a Spring Batch application, we have implemented an item scope.
Background
We have lots of #Service components which compute something based on the current batch item. Many of them need the same workflow:
Determine relevant item parts.
Init stuff based on the item.
For each item part, compute something (using stuff).
We moved the workflow into a base class template method, so the subclasses implement only findItemParts(Item) (doing 1 and 2) and computeSomething(ItemPart) (doing 3). So they became stateful (stuff initialized in findItemParts is needed in computeSomething), and that state must be cleared before the next item.
Some of those services also involve injected Spring beans which are also derived from the current item and must be removed afterwards.
Design
We implemented an AbstractScopeRegisteringItemProcessor which registers the item and allows subclasses to register derived beans. At the end of its process method, it removes the item from its scope context, and the derived beans using DefaultSingletonBeanRegistry.destroySingleton.
How it worked out
It works, but has the following problems:
We did not manage to get the derived beans cleaned up without registration (just based on their #Scope). The concrete processor must create and register them.
AbstractScopeRegisteringItemProcessor would have been nicer using composition and dynamically implementing all interfaces of the underlying processor. But then the resulting #StepScope bean is a proxy for the declared return type (i.e. AbstractScopeRegisteringItemProcessor or ItemProcessor) without the required callback interfaces.
EDIT
With the aid of #Eliot Sykes's solution and shared code plus #Cheetah's BeanDefinition registration, I was able to get rid of the registration as singleton beans. Instead, ItemScopeContext (the storage used by both the processor and the Scope implementation; Java-configured via a static #Bean method) implements BeanDefinitionRegistryPostProcessor. It registers a FactoryBean whose getObject() returns the current item or throws an exception if there is none. Now, a #Component annotated with #Scope(scopeName = "Item", proxyMode = ScopedProxyMode.TARGET_CLASS) can simply inject the item and need not be registered for end-of-scope cleanup.
So in the end, it did work out well.
A spring locale scope based on the users locale wihtin a web application
See related wiki page
In my company, we have also implemented spring custom scope. We have a multi tenant system where every customer can customize settings. Instance based scope of ours, caches the beans which are customer specific. So each time user of a customer logs in, these settings are cached and reused again when other users of the same customers sign in.
I once used a kind of conversation scope to store some objects in the session scope, in order to keep them when re-entering the same page, but limited to a single page to avoid to leave useless objects in the session. The implementation just stored the page URL and cleaned the conversation scope on each page change.

Categories

Resources