Why would we use custom scope in spring? When is it needed? - java

Can any one please help me in understanding custom scope. I went through manual and through many online example and understood how it is being implemented. But, I am still not clear why we need a custom proxy, and why we will go for, limiting the scope of the bean.
As i know that for a singleton- we use singleton when we want a single bean to be given to all references & we use prototype when we want a new reference to be given each time the bean is referenced.
Now my understanding regarding Custom scope is
Custom Scope- we use custom scope as a mid-way between the two that is neither we want to pass single reference nor a new reference every time.. but then it is more close to singleton where we are passing the same bean every time, just from our preferred location(such as underlying threadlocal or map).
please do help me making my concept clear ..The main question here is Why custom scope ? and When is it required?

In different context. For example - in a web application. Two scopes are defined there - "request" and "session". However, these are sometimes not sufficient. Often there is a need for a "flash" scope (lasts for one request and the subsequent redirect) or "conversation" scope (lasts for a sequence of requests forming a conversation).
In such, and similar cases, a custom scope is used.

That actually depends on the problem at hand. For instance, you might want to create a pre-defined number of instances of a particular bean, but not more than that. So until this number is met, you keep creating new instances, but once the number is met, you return existing instances in a balanced manner.
This could be applied to a problem where the instance takes up significant amount of resources (ex. memory) but speeds up the application if a new instance is used. So you could create a feasible amount of new objects when needed, and delegate into existing ones when the number of instances go beyond the that amount(compromising performance over resource utilization).

Related

Spring Singleton means no data sharing at class level?

I am confused.
Spring's default bean scope is Singleton. That means that once you define a bean of your class, every time a new "message" comes in, it will be processed by the same instance of that class.
But that also means that you cannot have mutable instance variables in that singleton bean because the next call of a method of that class will see data from past calls..
Example:
Calculator is my bean (singleton)
public class Calculator {
private List<String> operations = new ArrayList<String>();
public void calculate(String op, double val) {
operations.add(op);
// do some calculations
}
public List<String> getAllOperations() {
return operations;
}
}
Here's the client (useCalc is invoked many times!):
public class CalculatorClient{
#Autowired
private Calculator calculator;
public void useCalc () {
calculator.calculate("Add",100);
calculator.calculate("Div",100);
calculator.calculate("Diff",100);
List<String> allOperations = calculator.getAllOperations();
// Do something..
}
}
So let's say CalculatorClient useCalc gets called several times with different operations..
eventually operations in Calculator will contain all of the operations ever done on that calculator.
So the question is this:
Is this Spring's limitation - not being able to effectively share information between methods within a class? And if it is so, how to share that kind of information between methods?
I know there is the prototype bean scope. Is that the only solution in this case?
BTW, prototype is not a solution here because with prototype a new class will get instantiated with every call to calculator:
calculator.calculate("Add",100); // New
calculator.calculate("Div",100); // New
calculator.calculate("Diff",100); // New
And since Singleton is the default scope - aren't developers inadvertently introduce such bugs?
A common use case for singleton beans are to inject services into other objects.
Example, to provide an object a service to connect to the database, you "autowire" a database connection bean.
You don't want to create a new instance of the database every time, so singleton beans make sense.
Usually, the object itself that uses the autowire is a singleton as well (in a web app, the Controllers are also created just once, you don't want to create a controller for every request).
aren't developers inadvertently introduce such bugs?
Since the idea is to process several requests concurrently, all of those objects are usually already coded without having common state shared using instance variables.
This is not a "limitation", but rather a default for the most common use case.
I know there is the prototype bean scope. Is that the only solution in this case?
It sounds like a good "solution" to this, in that case a new bean will be created. Note that it would not make sense to autowire a prototype bean into a singleton since in that case there will only be once instance anyway.
Another possibility more commonly used is autowiring a singleton bean that acts like a factory, then ask that factory for a new object each time you need one.
The factory can be a singleton since you don't want more than one factory, but it would then return new objects in every call to its "create" method.
So in your example, you could do something like
#Autowired
private CalculatorFactory calcFactory;
public void useCalc () {
calculator = calcFactory.createCalculator();
calculator.calculate("Add",100);
calculator.calculate("Div",100);
calculator.calculate("Diff",100);
List<String> allOperations = calculator.getAllOperations();
// Do something..
}
}
There's a lot of conflation going on here. Let me try to unravel the premises.
The whole point of dependency injection is to make it so that you don't have multiple instances of a critical application service, which would lead to things getting out of sync or result in erratic behavior (e.g. multiple database connections, multiple access points to a JMS queue, multiple ways to query a database, etc).
It is not a mandate to make everything injectable.
If something is not inherently reusable, or you would not gain anything from registering it in the component scan, then there is no reason to make that thing either a bean or a component.
It is fairly reasonable to assume that beans shouldn't store state, but that doesn't mean that something else couldn't store that state on its behalf. For instance, you could put those operations into some other backing store as opposed to in-memory, and you'd still be able to keep the state of operations you've done.
The big thing that I'm seeing is that you've kind of implemented your Calculator class half-thinking that it was a bean, and half-thinking that it was newed up somewhere. By having that list in your class, you're subconsciously forcing yourself to hold onto the state in any instance created, which violated the inversion of control principle - you don't control the lifecycle of the object.
To get around this...you have a few options available.
Change how you're storing the state of your operations. Put it into a SQLite database or a file or somewhere that isn't dependent on an instance maintaining it.
Inject your own. You can create a bean that is of type List<String>, and require your Calculator to inject it when it's needed.
Don't create a bean. You can new this and Spring isn't really going to fuss at you. It'd make it harder to test, though.
The first two approaches abstract away the notion of storing the data from an operation and reading the data from the operations. You can either read from the injected operations bean or from the SQLite database or from the flat file to get the result of operations that you want.

How do you seed non scoped named bindings using Guice ?

Building a web based application using Guice and have this peculiar situation -
I am using a lot of method interceptors that are lightweight.
My question is - I have a named binding say "Operation.Current" the value of which needs to be changed when one of these interceptors executes within a single request thread. So the bound value changes multiple times within a single request thread. I need this value to be injected as I need.
Currently I am using
request.setAttribute(Key.get(Operation.class, Names.named("Operation.Current")).toString(), op);
in my GuiceFilter to initialize the value. And I want to replace this value when the interceptors execute.
So I need to re seed my value present in the request as an attribute multiple times through the request.
What is a better way to solve this issue ? Since I see that the value is not in a real sense RequestScoped. So ideally this value should be non scoped and bound the name.
But how do I change the value as I need outside a Guice Module ?
You cannot modify the module binding once you created the injector. If you know all instances in advance, try the MapBinder, otherwise consider using a provider-binding, then you can evaluate the required instance dynamically for each call.

demystification required on chapter 1 of Spring in Practice book regarding singleton beans not maintaining state

I am learning Spring and have found the book Spring in Practice to be an awesome source. I don't understand Spring bean singleton scopes completely however. And what I read in the section of bean scopes has confused me a bit.
Here is a excerpt from that section:
As you request singleton beans from the container, Spring will create
instances and cache them if they haven’t been created; otherwise,
Spring will return already-existing instances from its cache.
Therefore, singleton beans in Spring often don’t maintain state
because they’re usually shared among multiple threads (such as in
servlet environments). For example, singleton services often have
references to singleton DAOs, and the DAOs might have references to
Hibernate SessionFactorys, which are threadsafe.
Now I don't know much about multithreading in Java so please pardon my ignorance. In the above excerpt where it says "Therefore, singleton beans in Spring often don’t maintain state because they’re usually shared among multiple threads"
1). What does this mean for domain objects? Can I have a domain object called User defined as a singleton scope in the spring context? What would happen?
2). I notice that mostly datasources and large configurations are usually in the spring xml file. I have a feeling my questions relating to state and beans defaulting to singletons is related to wiring only big parts of an application.
Can someone clarify this topic for me? An example would be really helpful.
Thank you in advance.
A Java class is a description of state and behavior. An instance of that class is a holder of state that can exhibit behavior. Therefore, this class
public class Foo {
private String bar;
public Foo(String bar) {this.bar = bar;}
public void print() {System.out.println(bar);}
public void setBar(String bar) {this.bar = bar;}
}
describes a data structure which has a String as state and print() and setBar(String) methods as behavior. If you create an instance
new Foo("the state");
You now have an actual data structure that holds the String data (or state) "the state" and that can display that data by invoking the print() method or change it with setBar(String).
The problem with the class above is that it is mutable, ie. its state can change. If multiple threads are operating on it, you might see unexpected behavior. For example, one thread changes bar's value before another thread has the chance to print() out its previous value.
What does this mean for domain objects? Can I have a domain object
called User defined as a singleton scope in the spring context? What
would happen?
This means the exact same thing for domain objects as it does for service or presentation objects. You can very much have a domain object of type User defined as singleton scope in the Spring context. If you want to is a different question. Do you want your application to only ever have access to that one User instance? No, then don't make it singleton. Yes, then make it singleton. This only applies if Spring is actually managing the instances for you.
More clarifications:
It's important to understand what a Singleton is. Wikipedia says
restricts the Instantiation of a class to one object
If we are taking about restricted in regards to a JVM, a Singleton could be implemented as described here. If we are talking about restricted in regards to a Spring ApplicationContext, then we are talking about a Spring managed singleton scope bean (read the chapter carefully). For example
<bean id="customBean" class="org.mine.CustomBean" />
which is retrieved like
(CustomBean) context.getBean("customBean");
// or
context.getBean(CustomBean.class);
If we are always retrieving the instance from Spring's ApplicationContext, we are effectively only ever instantiating the class once.
So if that variable is being accessed by different parts of the
application, the state of the object can be changed by that variable
by executing for instance the setter methods on that variable. But
that seems like a singleton to me.
A web application is multi-threaded. If each thread is accessing the singleton bean and mutating it, you might get lost updates. These are typically not desired since you cannot predict them and therefore are hard to test.
That variable can be used to keep changing the same data structure
throughout different parts of the application. So how is the Foo
object not a singleton?
As stated earlier, Singleton is a pattern that describes how an instance is unique in regards to some context. Simply doing
new Foo("the state");
doesn't make that object a singleton. It's how you use it that makes it a singleton.
Well, if multiple threads change the same object at the same time, they'll interfere with each other. Most spring applications harness the power of multiple threads.
A singleton scoped bean corresponds to a single object (hence the name). Everyone asking for that bean will get the same object.
Therefore, you should not change that shared object.
What does this mean for domain objects? Can I have a domain object called User defined as a singleton scope in the spring context? What would happen?
Sure you could declare a bean of type user, but - as we learned above - everyone asking for that bean will get the same user object. Is this really what you want? For instance, if the bean is intended to represent the logged in user, this design would imply that only a single user can log in ...
On the other hand, if the bean merely holds configuration data that equally applies to all users, it would be quite reasonable to for the threads to share the same object (of course, if they change it, synchronization is required to prevent interference).
I notice that mostly datasources and large configurations are usually in the spring xml file.
That is indeed the typical use. Data that should be different for each thread is typically kept in local variables (or objects reachable from there). Because local variables are different for each method invocation, interference by other threads is not possible.
You can also use spring to manage short lived objects by declaring beans with a short-lived scope (such as session or request scope in a servlet environment) - though in that case, you'll have to take care that different threads don't access the state of the same object at the same time. With request scope, that's usually easy because requests are usually processed by a single thread. With session scope, you'll actually have to synchronize access.

How can I create a dynamic number of DefaultMessageListenerContainer MDPojos in Spring?

I need to create a variable number of these based on a configuration value, the intention is to have multiple consumers where each corresponds to a physical resource that can only be used by one thing at a time to process the message.
I implemented a container that manages multiple instances of DefaultMessageListenerContainer(s) which it creates based off of a prototypical instance if the listener. Based on a system property (a # value), a number of listeners are created and the queues they listen to are numeric "my.Queue" + ordinal number. This could obviously be modified to look up the queue names if necessary. That being said, this is not a dynamically expanding/contracting list of listeners. They are created at the beginning, although I think you could use this as a starting point to make it more dynamic if you wish to.
I wrote a pretty rudimentary unit test and a very rudimentary implementation (no multithreading taken into consideration), and it appears to work.
The maven project can be downloaded here -
http://dl.dropbox.com/u/7812537/StackOverflowMultipleListeners.zip
BTW - there's an interesting thread here - http://forum.springsource.org/showthread.php?t=69604
I think there could be a way to do this by extending a generic bean factory but i'm not sure what your requirements are.

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