Skip to content

August 4, 2010

4

JSF 2 with Spring 3 and JSR-330

Introduction

Recently I was involved in migrating an application from JSF 1.2 to JSF 2.0 with a stated goal of refactoring removing the plethora of JSF XML configuration files that permeated the codebase. Faces configuration files are notoriously difficult to maintain due to their verbose nature and reliance on the Expression Language (EL) syntax.

Other factors motivating the migration included:

  • Use of annotation-based configuration for managed beans across all layers within the application stack
  • Facelets templating for JSF views
  • Leveraging the Spring 3.x Inversion of Control (IoC) container support for JSR-330 – Dependency Injection for Java

Dependency Injection (DI) is a pattern for resolving component dependencies by having a container inject an instantiated component as opposed to explicitly instantiating a component from within an enclosing class.

Enable dependency injection within Spring

The Maven dependency for JSR-330 annotations can be referenced within a project POM file as follows:

<dependency>
	<groupId>javax.inject</groupId>
	<artifactId>javax.inject</artifactId>
	<version>1</version>
</dependency>

To enable Dependency Injection using JSR-330 annotations in Spring, the application context file must be updated with component scanning from the application base package as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:p="http://www.springframework.org/schema/p"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="

http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-2.5.xsd">

     <context:component-scan base-package="net.comdynamics.myapp"/>

</beans>

This configuration element triggers annotation-based autowiring with the base-package reflecting that of your application.

Services and data tier updates

The application services and data tier for the system had originally been developed using the Spring 2.5 framework. In order to leverage JSR-330 in Spring 3.x, changes were made to remove the @Service annotation and replace with the @Named annotation.

The @Autowired annotation for Data Access Objects (DAO) was changed to @Inject, with combined updates illustrated below.

Before

package net.comdynamics.myapp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("reportService")
public class ReportServiceImpl implements ReportService {

	@Autowired
	private ReportFilterDao reportFilterDao;

        // bean getters/setters…
}

After

package net.comdynamics.myapp;

import javax.inject.Inject;
import javax.inject.Named;

@Named("reportService")
public class ReportServiceImpl implements ReportService {

    @Inject
    @Named("reportFilterDao")
    private ReportFilterDao reportFilterDao;

    // bean getters/setters…

}

The @Named annotation is used to associate a name for the bean. If no name is specified as an argument to the annotation, the bean name will be the name of the class with the first letter set to lowercase.

The @Inject annotation is used to identify a dependency injection point for which a dependency on a Java class or interface can be set by the container.

The upshot of this change is that bean references using the @Named annotation can be removed from the Spring application context. For example, after making changes above, the following bean declaration can be commented out deleted.

    <!--
    <bean id="reportService" class="net.comdynamics.myapp.ReportServiceImpl" />
    -->

JSF managed bean updates

JSF2 introduced the @ManagedBean annotation which was intended to minimise Faces configuration in XML files. Whilst this alleviates the need to declare JSF managed beans in XML it does not promote annotation consistency across all layers in the application.

To ensure consistency in a Spring project and alignment with JEE 6, use the JSR330 @Named annotation for JSF backing beans. For example:

package net.comdynamics.myapp.web;

import javax.inject.Named;
import org.springframework.context.annotation.Scope;

/**
 * ReportListPage JSF backing bean.
 */
@Named("reportListPage")
@Scope("request")
public class ReportListPage extends BasePage {

    @Inject
    @Named("reportService")
    private ReportService reportService;

    public ReportListPage() {
    }

    public ReportService getReportService() {
        return reportService;
    }

    public void setReportService(ReportService ReportService) {
        this.reportService = reportService;
    }

    // etc…

}

Failure to set the scope of the managed bean will result in Spring creating a Singleton instance for that bean. For JSF beans, specify the scope as Request or Session as either @Scope("request") or @Scope("session")

After making the above change, JSF managed bean references in the faces configuration files can be commented out deleted.

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version='1.2' xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">

        <!--
	<managed-bean>
		<description>Backing bean for Report List page</description>
		<managed-bean-name>reportListPage</managed-bean-name>
		<managed-bean-class>net.comdynamics.myapp.web.ReportListPage</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
		<managed-property>
	    	<property-name>reportService</property-name>
     		<value>#{reportService}</value>
	   	</managed-property>
	</managed-bean>
        -->

</faces-config>

Conclusion

Use of annotation-based configuration for managed beans across all layers within the application stack can simplify configuration and enforce consistency. Spring 3.x supports JSR-330 which can be leveraged by your JSF 2 application with minimal effort.

CDI (JSR-299) scopes and JSF 2 backing beans will be discussed in a future article.

Read more from JSF, Spring
4 Comments
  1. Karol
    Mar 19 2011

    Very useful! Thanks for sharing this information.

  2. Danilo Chagas
    Dec 3 2010

    Reeeealy nice post! Simple, concise and works pretty well! I wish I had come across this web site sooner. Congratulations!

  3. Oct 7 2010

    Sorry for my bad english. Thank you so much for your good post. Your post helped me in my college assignment, If you can provide me more details please email me.

  4. Aug 19 2010

    Nice post and this mail helped me alot in my college assignment. Say thank you for your information.

Comments are closed.