tags:

views:

945

answers:

5

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.

+2  A: 

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.

Andrzej Doyle
Really cool, you expanded my horizon there. I see a "cached" scope or similar. Probably also nice for calculated derived data, which is what it seems like you're doing.
krosenvold
+2  A: 

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.

cliff.meyers
We solved this by using mock session/request objects in the JUnit context instead, so we have request/session scope avilable. Would these two solutions be functionally equivalent ? (Could probably be used in the quartz scope too ...)
krosenvold
For the differences between JUnit and the Servlet context, I definitely think they're equivalent. For Quartz, I think it's a bit more complicated. If you are injecting scoped beans into your services and trying to call those services from a Quartz job, it would be difficult to workaround that.
cliff.meyers
I've no experience with quartz, but does it run in a single thread or different threads?
krosenvold
To be precise, we have our own ContextLoader that registers the scopes request and session for unit tests. The implementations of these scopes is based on the spring versions of these scopes. Couldn't this approach be used for quartz ?
krosenvold
+1  A: 

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.

cletus
+1  A: 

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:

I've put together a Site Scope howto and sample code here

http://blog.eliotsykes.com/2010/03/05/spring-custom-scopes-site-scope-howto/

and here

http://github.com/eliotsykes/spring-site-scope

Eliot Sykes
+1  A: 

Apache Orchestra provides SpringConversationScope.

Roman