Leveraging Spring Beans in ADF Faces applications and using the Spring PropertyPlaceholderConfigurer bean to dynamically configure bean properties from external files

0

The Spring Framework is omnipresent in the world of Java applications. Many developers, teams and organizations make use of Spring for various reasons, such as its persistency support, the AOP features, the MVC framework or the remoting options or the security facilities. Underlying all of these is the bean container, that started it all, with its implementation of the Inversion of Control pattern and the concept of Dependency Injection. The managed beans in JavaServer Faces share many of the same characteristics of the Spring Beans – the configuration in XML (and starting with JSF 2.0 also through annotations), the use of managed properties and injecting one bean in another.

It should then not come as a surprise that it is fairly easy to integrate the Spring Framework with JSF applications. EL expressions can refer to beans – as always. And those beans can either be defined in the faces-config.xml file – or through annotations in Java Classes – or as beans in the Spring way: either in an XML configuration file or through annotations. This article will demonstrate this and show the minimal effort required to integrate Spring into JSF – and thereby also into ADF Faces.

We will then move on to leverage a specific Spring feature – the PropertyPlaceholderConfigurer class – that allows us to use EL expressions for managed properties and have those expressions evaluated against external property files and System Properties. Using that particular class allows us to have managed beans in our JSF application that get their properties set based on the porperties defined in a property file.

Load the Spring plugin in JDeveloper

Using Help => Check for Updates, locate the offical Oracle extension and have it installed:

Image

Note: this is not the only way to get Spring set up in your environment, but it is probably the easiest.

Press Next, have the extension downloaded:

Image

And restart JDeveloper when prompted:

Image

Create a Fusion Web Application and add the Spring 2.5 library to it

Create a Fusion Web Application (or Java EE Web Application or just a generic application) in the normal way. Then add the Spring 2.5 library to the application.

Image

Extend Faces-Config.xml with Spring Bean EL Resolver

The SpringBeanFacesELResolver needs to be set up in the faces-config.xml to instruct the JSF framework to allow Spring to resolve EL expressions (when the JSF managed bean definitions are not enough to get the job done).

  <application>
    ...
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
  </application>

Configure Spring Bean container in web.xml

To have the Spring Bean container initialized along with the application, to entries have to be added to the web.xml file. One to load the Spring Bean context – using the ContextLoaderListener -and one to configure the Spring bean configuration file(s) that are used to configure the context.

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/the-beans.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

Create Spring Bean configuration file

The Spring Bean configuration file contains the definitions of the Spring beans, very similar to the Managed Bean definitions in faces-config.xml. Here we have a single bean definition, for a bean called someBean, based on a disappointingly sad little class:

    <bean id="someBean" class="nl.amis.someapp.view.MyBean">
        <property name="companyName">
            <value>FortuneTeller Inc.</value>
        </property>
        <property name="greeting">
            <value>Hello Everyone</value>
        </property>
        <property name="status">
            <value>Status OK</value>
        </property>
    </bean>

Create the JSF page that makes use of the Managed Bean (that is actually a Spring Bean)

We can create a simple JSF/ADF Faces page that makes use of the managed bean to display a number of values on a page:

Image

Turn the Bean’s managed properties into property-file driven properties

Bean properties in Spring Bean configuration files can be specified through EL expressions that are evaluated against property files. This evaluation is done by a Spring PropertyPlaceholderConfigurer bean that needs to be configured in one of the bean configuration files. This PropertyPlaceholderConfigurer is associated with one or multiple property files that it will scan to resolve expressions like ${property}: it will simply look in every property file for a property entry that consists of property=value and it will replace the expression with the value found in this manner.

The PropertyPlaceholderConfigurer bean is configured in this example like this:

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
        <list>
            <value>classpath:/META-INF/project.properties</value>
            <!-- pass targetEnvironment as System Property: -DtargetEnvironment=dev -->
            <value>classpath:/META-INF/${targetEnvironment}-env.properties</value>
            <value>file:/c:/temp/global.properties</value>
            </list>
        </property>
    </bean>

Three different property files are used here. One is in the META-INF directory on the classpath (project.properties), one is on a global path: c:\temp (global.properties) and one is not entirely determined itself: classpath:/META-INF/${targetEnvironment}-env.properties. The name of the file itself contains an expression that needs to be resolved. Here we make use of the fact that the Spring PropertyPlaceholderConfigurer will also check against the Java System properties if it cannot find a property you are trying to use. As startup argument we pass the value of a system property called targetEnvironment with a value like dev or test.

Image

Depending on the value of this system property, either the file dev-env.properties is scanned for property values or the test-env.properties. These files presumably contain the same properties, with values that are appropriate for their respective environments.

Image

We can now change the property definitions for the someBean bean, using expressions that will be evaluated against these property files:

    <bean id="someBean" class="nl.amis.someapp.view.MyBean">
        <property name="companyName">
            <value>${company.name}</value>
        </property>
        <property name="greeting">
            <value>${resources.greeting}</value>
        </property>
        <property name="status">
            <value>${environment.status}</value>
        </property>
    </bean>

The property files themselves are not all that interesting:

Image

Image

Resources

Download JDeveloper 11gR2 application: JsfSpringProperties.

Spring Framework 2.5 documentation on PropertyPlaceholderConfigurer http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-extension-factory-postprocessors

Blog article with clean straightforward for propertyplaceholderconfigurer and useful comments as well: http://almaer.com/blog/spring-propertyplaceholderconfigurer-a-nice-clean-way-to-share

Share.

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director for Fusion Middleware. Consultant, trainer and instructor on diverse areas including Oracle Database (SQL & PLSQL), Service Oriented Architecture, BPM, ADF, Java in various shapes and forms and many other things. Author of the Oracle Press book: Oracle SOA Suite 11g Handbook. Frequent presenter on conferences such as JavaOne, Oracle OpenWorld, ODTUG Kaleidoscope, Devoxx and OBUG. Presenter for Oracle University Celebrity specials.

Leave a Reply