Using CDI Scopes with Spring 3

With the advent of Spring 3 the framework now supports the Java Injection standard (JSR 330). However, unfortunately, they do not support the scoping, which is introduced in Java EE 6,through the CDI specification (JSR 299).

Now the big difference between a JSF “managed bean” in Java EE 6 and Spring is that they basically use a different scoping (JavaEE vs. Spring)!

However, the remaining parts are exactly the same, in both worlds:

  • @Named and Qualifiers for for naming and type-safety…
  • @Inject to identify “injection points” for dependencies/resources…

During our JAX 2010, Lars Röwekamp and I showed how enable the Spring Framework to understand the CDI scopes, such as @RequestScoped or @SessionScoped.

Before that, I spoke to Juergen Hoeller on the JAX conference, and he explained me the underlying mechanism and how something like that could be easily done!

The Spring Framework uses a ScopeMetadataResolver to resolve the SPRING-based scopes of the bean definitions. To actually enable the CDI scopes I “decorated” their default implementation, the AnnotationScopeMetadataResolver class:

public class CdiScopeMetadataResolver
extends AnnotationScopeMetadataResolver
{
 @Override
 public ScopeMetadata resolveScopeMetadata(BeanDefinition definition)
 {
 ScopeMetadata metadata = new ScopeMetadata();
 if (definition instanceof AnnotatedBeanDefinition)
 {
 AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
 Set<String> annotationTypes = annDef.getMetadata().getAnnotationTypes();

 if (annotationTypes.contains(
 javax.enterprise.context.RequestScoped.class.getName())
 )
 {
 metadata.setScopeName("request");
 }
 else if (annotationTypes.contains(
 javax.enterprise.context.SessionScoped.class.getName())
 )
 {
 metadata.setScopeName("session");
 }

...
//more...
//
 else
 {
 // do the regular Spring stuff..
 return super.resolveScopeMetadata(definition);
 }
 }
 return metadata;
 }
}

The CdiScopeMetadataResolver class scans the actual Spring beans and checks if the CDI
scope annotations are declared. If they are present we simply map them to their corresponding
Spring scopes!

So the trick is that you annotate them with CDI, but under the hood they are Spring scopes!

Now in your Spring configuration you simply enable it like:

...
 <context:component-scan
base-package="my.packages..."
scope-resolver="...CdiScopeMetadataResolver" />
...

Now you are able to define your Spring/JSF beans with 100% JavaEE-based annotations.

UPDATE: I published the code of this class to github.

Enjoy!

About these ads

Howdy!

Posted in apache, CDI, ejb, java, jsf, myfaces, seam, spring, WebBeans
5 comments on “Using CDI Scopes with Spring 3
  1. struberg says:

    That’s great stuff!
    I’d be happy if Jürgen provides that functionality with an upcoming Spring release out of the box though.

  2. [...] UPDATE: Enabling the CDI/299 Scopes in Spring is pretty simple. [...]

  3. [...] CDI Scope Resolver for CDI 15 09 2010 A few weeks ago I blogged about a simple Spring Resolver to integrate CDI standard scopes in a Spring-based application. I [...]

  4. [...] frameworks such as Spring (…) was envisaged by the designers of CDI“. I did find this blog that simulates CDI features by enabling Spring ones. What I didn’t find is a clear statement [...]

  5. [...] For the scoping, i must still use @Scope(“request”) or @Scope(“session”), but if i prefer the @RequestScope (javax.enterprise.context.RequestScoped) and @SessionScope, i can make use of the bridge provided from this article. [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 34 other followers

%d bloggers like this: