I have the following design. When a client makes a request to the server, the server creates a state that holds all sorts of info. There are various stateless and stateful beans which need to read and write to this state. Refer to this unprofessional diagram:
The ComputationCycle class is where the processing starts and works by phases. During each phase it calls upon other Manager classes (which behave like utility classes) to help in the computation (diagram shows only for 1 phase). The state is being read and written to both from the CC class and the managers, both are stateless.
State holds Employee, Department and Car classes (in some irrelevant data structure) which are stateful. These classes can also call the Manager classes. This is done by a simple #Inject Manager1. The same way CC uses managers.
My problem is how to access the stateful state (and its contained classes) from the stateless classes (and from the Car, Department and Employee classes too, although I think solving one will solve the other). I can't inject a stateful bean into a stateless bean. So after the client makes a request and the computation cycle starts, how do I access the state related to this request?
One solution is to pass the state to every method in the stateless classes, but this is really cumbersome and bloaty because all methods will have an "idiotic" State argument everywhere.
How can I make this design work the way I want it to?
I can't inject a stateful bean into a stateless bean.
You can absolutely inject dependencies this way.
If the stateful bean is #RequestScoped, any call into the stateless bean on that thread that hits a CDI injected contextual reference (iow proxy) will find its way to the right instance of the stateful bean.
As long as you use CDI, you don't need to trouble yourself with trying to stash things away in your own threadlocals.
Buyer beware, ThreadLocal will possibly do what you're wanting, along with a static accessor. However, this class is prone to causing memory leaks if you are not extremely careful to remove each entry at the end of the request. In addition, you seem to be using EJB; I assume they are all in the same JRE. I use ThreadLocal quite a bit in similar situations, and I've had no problems. I use SerletContextListener's to null the static reference to the ThreadLocal when the context shuts down, although that has been problematic on some older Web app servers, so I make sure the ThreadLocal exists before attempting to use it.
EJB can "talk" to each other across servers. It sounds local all your EJB are running in the same context.
Create a class that holds your state.
Extend ThreadLocal--you can do this anonymously--and override initialValue() to return a new instance of your class.
Create a utility class to hold the ThreadLocal as a static field. Don't make it final Create static fetch and remove methods that call ThreadLocal.get() and remove(). Create a static destroy() method that is called when your context shuts down--see ServletContextListener.
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.
The SessionContext.getBusinessObject() is described in the docs as follows,
Obtain an object that can be used to invoke the current bean through the given business interface.
Parameters:
businessInterface - One of the local business interfaces or remote business interfaces for this session bean.
Returns:
The business object corresponding to the given business interface.
Can't I use the 'this' keyword in Java instead, to accomplish the same ? How are these different ?
The motivation here is that most EJB implementations work on proxies. You wouldn't be too far off in thinking of it as old-school AOP. The business interface is implemented by the EJB container, quite often via a simple java.lang.reflect.Proxy, and this object is handed to everyone in the system who asks for the ejb via #EJB or JNDI lookup.
The proxy is hooked up to the container and all calls on it go directly to the container who will preform security checks, start/stop/suspend transactions, invoke interceptors, etc. etc. and then finally delegate the call to the bean instance -- and of course do any clean up required due to any exceptions thrown -- then finally hand the return value over through the proxy to the caller.
Calling this.foo() directly, or passing 'this' to a caller so they can make direct calls as well, will skip all of that and the container will be effectively cut out of the picture. The 'getBusinessObject(Class)' method allows the bean instance to essentially get a proxy to itself so it can invoke its own methods and make use of the container management services associated with it -- interceptors, transaction management, security enforcement, etc.
I am new to EJB. I have a requirement of calling a method of remote stateless bean and setting a value, before calling any method on the same bean. The value set from first method call should be available to second method. I know that a stateless bean can't hold instance variables values for next calls. Is there any alternative to make the value available to the bean method without making bean as stateful bean. any tweaking tip?
Is there any alternative to make the value available to the bean method without making bean as stateful bean?
Without passing the value to the second method or persisting it, for example in database, I don't think so (using an instance variables is certainly not a solution as you're not sure to call the same session bean with each method call because the pool can return any session bean for your method call).
It is a wrong use of stateless session bean. Stateless should depend upon only the parameters that are being passed to it and no other previous state. Even if you put a hack around it, think of poor guys who will support it later.
Database is definitely a better way of doing it. Otherwise, can you use interceptors ? They are powerful in EJB 3.0 and can even change the parameters, set some value etc.
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.