Monday, April 7, 2014

spring managed vs jsf managed

  • spring managed beans vs jsf managed beans?

your beans should be completely managed either by JSF or by Spring.

Many web applications consist from several 'layers' also called as 'tiers' of the application: web tier, or presentation tier for viewing pages of your application, business tier, or middle tier for executing logic and business rules of your appication and data tier, or persistece tier for tranferring data to/from your database. These tiers might have the following configuratio



  1.     Entity classes that will hold data derived from your database and most plausibly used by an ORM framework like Hibernate;
  2.     DAO classes that will be used to access database and at least perform CRUD operations on the database and most importantly for your web part return Entity classes for your web tier;
  3.     Service classes that will reflect business operations you application provides for;
  4.     Bean classes that will back up your views and will most probably contain data, action methods, transformations etc. used in your web pages.

    The next step is the choice of framework for your web application.
   
  1.     You choose Spring for all layers which means that your DAOs will be @Repository classes, your Services will be @Service classes and your Beans will be @Component classes. You will most probably use an ORM framework like Hibernate to deal with the database, so your Entities will be JPA @Entity classes properly configurated in Hibernate style. Your view technology will most probably be Spring MVC that was elaborated to work with Spring core 
  2.     You choose native JSF+EJB framework for all layers which means that your DAOs and Services will be @EJB classes your beans will be @ManagedBean classes. You will most probably also use Hibernate as ORM solution and JPA provider and will do database access via EntityManager. Your view technology will be JSF as it was naturally intended to be used with the abovementioned technologies.
   
   
    Spring is a lightweight container that will run on simple servlet containers like Tomcat whereas EJBs need an application server like Glassfish to run on. I think that this is the major driving force for combining JSF as a component-based web framework and Spring as a lightweight dependency injection and business tier framework.
   
   
    As we decided to integrate both frameworks together, I will explain how the integration works and why NPEs occur.

  1.     Entity classes will either be JPA/Hibernate annotated classes or simple POJOs configured by xml.
  2.     DAOs will be @Repository implementing base interfaces to avoid tight coupling. They will be managed by the Spring framework.
  3.     Services will be @Service also implementing base interfaces. They will also be managed by the Spring framework. Note that Spring framework will provide for out-of-the-box transaction management for you if you mark service methods with @Transactional.
  4.     Beans therefore must be @Component and @Scope("value") and must be managed by Spring if you want to use it as a dependency injection framework, allowing to access your services and other beans via @Autowired.

   
    So, the NPE stems from misunderstanding that your beans, as a logical part of the view, should be managed by JSF (note that @ManagedProperty wouldn't work as well). The bean gets instantiated by JSF, but your service resides in Spring context that JSF knows noting about, making injection not possible. On the other hand, if the bean remains within Spring context, its lifecycle and dependencies will be injected by Spring
   
   
    So, to make it work, mark the bean as

    @Component
    @Scope("request")
    public class SpringManagedBeanToBeUsedByJSF {

        ...

        @Autowired
        private SpringService springService;

        ...

    }
   
    and make all the prerequisites of using Spring with JSF.
    Consult this excellent example
    http://www.mkyong.com/jsf2/jsf-2-0-spring-hibernate-integration-example/
    This way, all of the beans will be managed by Spring and will be visible in JSF views when you attach EL-resolver in faces-config.xml (allowing JSF to 'see' Spring beans) and necessary listeners in web.xml.
    When you do it like this, all of the Spring beans can be referenced in .xhtml files and if you need to put the JSF action in the bean, just go ahead and place them in the (Spring) managed beans or make them implement vital to JSF interfaces, etc.
    The integration can be achieved only this way. Of course, you can also use JSF managed beans, @FacesConverter and @FacesValidator classes in the application as well, just do not interfere them with each other, but using two dependency injection frameworks withing one application is at least confusing.
   
    http://stackoverflow.com/questions/14766345/spring-dao-is-not-injected-in-jsf-managed-bean



  • To make a Java bean a Spring-managed service bean, you use the @Component or @Service annotation.


    @Component: a generic stereotype for any Spring-managed component.
    @Repository: used in the persistence layer to declare a Spring-managed DAO component.
    @Service: used in the service layer to declare a Spring-managed business service facade.
    @Controller: used in the presentation layer to declare a Spring-managed controller, for example a web controller.

   
    http://steveschols.wordpress.com/2011/07/28/spring-factorybean-managed-wiring-part-2/
   
   
    JSF is a component based web framework with an emphasis on MVC. Spring is a Dependency Injection and Inversion of Control framework that is not exclusive to web applications.
   
    If you don't understand these three terms are:

    Component based web framework

    Dependency Injection

    Inversion of Control

Then my suggestion is that you just stop what you are doing and immediately begin reading.


JSF as a standalone framework maintains the scope of its own managed beans without the need for a seperate DI framework. When introducing Spring however then there are naturally going to be conflicts. Spring manages its own Beans apart from JSF, so to reference these ManagedBeans and have business objects or DAO's be properly injected into them for use, the JSF ManagedBeans need to become Spring Controllers.


You can declare a JSF ManagedBean with the @Controller annotation. Spring 3 is smart enough to recognize that it is a JSF managed bean and the bean name will be whatever the name is declared as for the ManagedBean.

@Controller
@Scope("session")
@ManagedBean(name="testBean")

The EL Resolver does basically just that, it resolves EL expressions encountered on your XHTML/JSF page. When referencing testBean however it will not be able to resolve this name correctly as it is referring to a JSF managed bean by that name, and will not be able to find the Spring Controller with all the Spring injected dependencies that you need.

Spring 3 solves this problem by providing you a custom EL Resolver to use in place of the one that comes bundled with your JSF implementation. You can declare it to be used in faces-config.xml

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


If you are just integrating JSF + Spring without the need for any other Spring controlled Servlets or without the need for Spring Security integration then no you do not need anything additional in your web.xml. You would only need to declare the FacesServlet and its context params, plus any other third party component library servlets that may be necessary for your situation.

http://stackoverflow.com/questions/12317288/how-to-declare-a-jsf-managed-bean-in-a-spring-3-1-application



  • spring managed?

@Component
@Scope("session")
public class AddressBean {
}

vs

jsf managed?
@ManagedBean
@SessionScoped
public class AddressBean {
}


If you were already using Spring for IoC, and if you were to, say, deem it 'cleaner' or 'easier' to use one IoC container for the management of the beans in all of your layers, it is possible to add a resolver to your faces-config.xml file in order to instruct JSF to utilise the Spring container instead:
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>


If you are using JSF and have JSF pages (views) and such, then it could be JSF managed beans.
Likewise if you have a Spring MVC project it would be Spring beans.

http://stackoverflow.com/questions/13987826/spring-3-vs-jsf-2-managed-beans



  • Injecting Spring Beans into JSF 2 @ManagedBean Classes

This particular example is taken from some PoC work done with JSF 2 and Spring 3 running within a Tomcat 6 server (on JDK 5). The reason I wanted to inject Spring references into my JSF managed beans was both for ease of use, and because we haven’t made a decision architecturally (yet) to use JAX-WS or Hessian web services, and the only change would be the Spring configuration of the service definition.

I then attempted to get Spring to manage the bean, and found that JSF is able to delegate resolution of managed beans to an external resolver if it is configured correctly. In order to achieve this functionality the following needs to be done:

web.xml
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

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

Each backing bean into which you wish to inject Spring references into needs to be managed by Spring, so need to be annotated with Spring stereotypes.
page1_backing.java
package com.test.jsf;

@ManagedBean
@Controller
@Scope(value = "request")
public class page1_backing
{
    @Autowired
    private UserInfo ui;

    ...
}

The @Autowired annotation is a Spring annotation indicating that the reference will be injected when the Spring bean is created. As the bean is scoped to “request”, the managed bean will be created each time it is referenced by the JSF request lifecycle. In this example, the UserInfo class is a simple POJO that contains user-sensitive data such as forename, surname etc.


The final piece of the puzzle is to add the component-scan annotation to the Spring configuration file so that stereotypes are automatically picked up when the Spring context is loaded.

application-context.xml
1
   
<context:component-scan base-package="com.test.jsf" />

http://deevodavis.wordpress.com/injecting-spring-beans-into-jsf-2-managedbean-classes/

No comments:

Post a Comment