Spring 3.0 and JSR 330: Using @Inject

In here I showed how to use the @Named with Spring 3 to create “named beans”, to be used in frameworks like JSF2… Since we usually want to inject service implementations into our JSF beans, we need to use the @Inject from the JSR 330 (of course the regular Spring DI mechanism works as well). The JSF bean could look like:

@Model
public class SimpleBean
{
@Inject Service service;
...
public void callSomething()
{
service.myStuff();
...

Now we need to have an implementation of the Service interface. In order to allow the Spring Framework to find the (right) implementation the class itself needs to be annotated with the @Component annotation (or one of its specializations, like @Service which marks the class to be a “business service facade”):

@org.springframework.stereotype.Service
public class ServiceImpl implements Service
{
...
}

If your class (->interface implementation) does not have a meaning like that, you could simply use the @Named annotation from the JSR 330, like:

@javax.inject.Named
public class ServiceImpl implements Service
{
...
}

The good news with @Named and Spring here is that you could also combine the “Component” annotations and the @Named. This is useful if you have multiple implementations, like:

@org.springframework.stereotype.Service
@javax.inject.Named("bonusCustomerSerivce")
public class ServiceImpl implements Service
{
...
}

The injection point inside of your “clients”, like the JSF managed beans now also need to use @Named(“bonusCustomerService”) if the bean wants to use this specific one. The @Named usage may look a bit verbose, but there is help. You could create your own annotations, leveraging the @Qualifier from JSR 330. This is also supported in Spring3…

Good news here is (again) that most of the Dependency Injection “API” is similar in JavaEE 6 and Spring 3. You can used the @Inject, @Named and/or custom @Qualifiers (more soon). Right, there are also some differences between the two, but that’s coming in a later post…

Spring 3.0 and JSR 330: Using @Named

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!

Trinidad: JSF state-saving per page

In a JSF/Trinidad application the “state-saving” is configured via some parameters in the web.xml file. Trinidad adds a bit more to it with its TOKEN approach, check the documentation for the “org.apache.myfaces.trinidad.CLIENT_STATE_METHOD” to read more. The result of the configuration via WEB.XML file is that the entire configuration for the state-staving behavior is GLOBAL. In Trinidad most of the time we use a hybrid approach (server+token on client), but sometimes you want a specifc page to be just client-side, to avoid nasty “session expired errors”. A good example would be a login page, to have (client-only) state – of course a totally stateless page would make sense too, but this means a login page is created outside of the (Trinidad/JSF) framework.

We recently introduced a new feature to enable the configuration of the state-saving on a per-page base! For that we introduce a new attribute on the <tr:document> component (stateSaving). The “stateSaving” attribute takes three different values:

  • client (force to be (full) client)
  • server (force to be server-side)
  • default (do what ever the user said in web.xml)

So with this it is possible to tweak the state-saving on a per-page base, instead of all done globally!