Lightweight JSF with Guice

One of the shortcomings of JSF 1.2.x is it’s xml based simple IOC container. stuff repeats and repeats once application gets larger and it only allows setter injection with no AOP support. So it’s almost the basic IOC container you can think of. Usually JSF IOC is totally left out because of it’s incapabilities and more complete containers like spring or seam injection is used to create the JSF backing beans leaving managed beans alone. JSF 2.0 comes with the @ManagedBean annotation which actually should be in JSF 1.2 instead. @ManagedBean sounds fine but still the ioc part have shortcomings I’ve mentioned above.Also I don’t like the fact that for a simple managed bean we need to add another annoation for scope like @SessionScoped. It may become annotation hell as well.

PrimeFaces Optimus module provides non-rendering JSF solutions like xml-less navigation handler and guice integration. With Guice integration you can use Guice powered lightweight pojos as JSF backing beans and take the advantage of field, constructor, setter injection, aop support and more guice features. Following is a simple optimus backing bean annotated with @Controller.

import org.primefaces.optimus.config.Scope;
import org.primefaces.optimus.config.annotations.Controller;

@Controller(name="greetingController", scope=Scope.REQUEST)
public class GreetingController {

	private String message = "Merhaba";

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}

This can be used on a page as;

	<h: outputText value="#{greetingController.message}" />

Example above is the simplest form. The nice part is that @Controller annotated beans are actually Guice powered meaning they realize the @Inject annotation and have aop capabilities. Suppose you have a guice managed service called MovieService and a MovieController for JSF backing.

public interface MovieService {
    public void saveMovie(Movie movie);
}

And the implementation

public class MovieServiceImpl implements MovieService{

    public void saveMovie(Movie movie) {
        //save movie here
    }
}

Next thing is to add MovieService to your Guice Module and configure it for Optimus,

public class MovieStoreMainModule implements Module{

    public void configure(Binder binder) {
        binder.bind(MovieService.class).to(MovieServiceImpl.class).in(Scopes.SINGLETON);
    }
}

And let optimus know about your modules;

<context-param>
<param-name>optimus.CONFIG_MODULES</param-name>
<param-value>org.primefaces.examples.config.MovieStoreMainModule</param-value>
</context-param>

That’s it now you can inject the movie store to a JSF backing bean;

Simple Injection

import org.primefaces.optimus.config.Scope;
import org.primefaces.optimus.config.annotations.Controller;

import com.google.inject.Inject;

@Controller(name="movieController", scope=Scope.REQUEST)
public class MovieController {

    @Inject
    private MovieService movieService;

    public String save() {
        movieService.save();
    }
}

Constructor Injection

import org.primefaces.optimus.config.Scope;
import org.primefaces.optimus.config.annotations.Controller;

import com.google.inject.Inject;

@Controller(name="movieController", scope=Scope.REQUEST)
public class MovieController {

    private MovieService movieService;

    @Inject
    public MovieController(MovieService movieService) {
        this.movieService = movieService;
    }

    public String save() {
        movieService.save();
    }
}

Setter Injection

import org.primefaces.optimus.config.Scope;
import org.primefaces.optimus.config.annotations.Controller;

import com.google.inject.Inject;

@Controller(name="movieController", scope=Scope.REQUEST)
public class MovieController {

    private MovieService movieService;

    @Inject
    public void setMovieService(MovieService movieService) {
        this.movieService = movieService;
    }

    public String save() {
        movieService.save();
    }
}

AOP Support

Since guice powered jsf backing beans are AOP aware, I’ve added some utilities to make use of this, I’ll discuss this more in later when posting about Optimus Security Extensions but as an example Method Level Security is implemented with Guice AOP support. If users do not have the suitable role a security exception is thrown.

import org.primefaces.optimus.config.Scope;
import org.primefaces.optimus.config.annotations.Controller;
import org.primefaces.optimus.auth.Authorize;
import com.google.inject.Inject;

@Controller(name="movieController", scope=Scope.REQUEST)
public class MovieController {

    @Inject
    private MovieService movieService;

    @Authorize("admin,webmaster")
    public String save() {
        movieService.save();
    }
}

Optimus

Combined with the XML-Less Navigation Handler in optimus then you don’t need any repetitive <navigations /> in faces-config.xml. To sum up, Guice powered JSF gives more lightweight, low footprint and flexible solutions without the burden of xml or other huge ioc containers bloated with features you don’t need. More information about PrimeFaces Optimus is at the homepage of PrimeFaces.

One Response to Lightweight JSF with Guice

  1. matthiaswessendorf says:

    This is a really interesting library, I like the non-rendering part of it. Good job! Done well!

%d bloggers like this: