The Spring 3.x release comes with a build-in support for the JSR 330, called “at inject” (or Dependency Injection for Java). So it is now possible to use these annotation as an alternative for the @Autowired et al.
The benefit of the JSR330 is that it is supported in different environments:
- JavaEE 6
- Spring 3.0
- Guice 2.0
So the dependency base for all these frameworks is now the same, with some small differences. Using JSR330 with Spring is actually very simple. In your application-context.xml file you need to have the <context:component-scan> element, like:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" ...> <context:component-scan base-package="net.wessendorf" /> </beans>
Now the annoations can be used in your classes:
package net.wessendorf.spring;
import java.io.Serializable;
import javax.inject.Named;
import org.springframework.context.annotation.Scope;
@Named("mybean")
@Scope("session")
public class SimpleBean implements Serializable
{
...
}
The above snippet defines a session-scoped bean, which has the name “mybean”. So when using the SpringBeanFacesELResolver class (for JSF), your XHTML page can easily use the bean in it…
In CDI there are similar annotations for scoping, like RequestScoped, SessionScoped or ApplicationScoped. Spring has just one Scope annotation which itself takes the actual scope as its parameter. CDI also has a convenience annotation which combines @Named and @RequestScoped, and you can create similar ones, as extensions.
Of course this is possible with Spring 3.0 as well:
package net.wessendorf.spring.stereotype;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Named;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Named
@Scope("request")
@Component
@Target( { TYPE, METHOD, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Model
{ }
The interesting part is the @Named, which makes the name available, the @Scoped, which is set to request on your new @Model annotation and the @Component to mark the annotated class a as “Spring component”. Now instead of always adding @Named and @Scope(“request”) you could simply use the new @Model:
@net.wessendorf.spring.stereotype.Model
public class TesterBean
{
...
}
Now the above TesterBean can be resolved as “testerBean” in your JSF XHTML page.
Have fun!
Great stuff! I believe the @Component annotation for @Model is not needed. Also you probably want to limit the target to Type only.
Hi Eberhard,
I tried that, but I had to include it (like @Repo/Service do). But I really like the 330 support style in Spring. Good stuff.
Hi,
I have yet to see anything on what it takes to make JSR-330 annotated code interoperable between Spring and Guice in terms of configuration differences. Have you investigated this?
Pingback: Using CDI Scopes with Spring 3 « Matthias Wessendorf's Weblog
Pingback: Injeção de Dependência em Java « Victor V. Serta's Tech Blog