Friday, February 3, 2012

Using Spring to Manage JSF Beans

http://cagataycivici.wordpress.com/2007/09/10/using-spring-to-manage-jsf-beans/

SEPTEMBER 10, 2007 30 COMMENTS
The traditional way to integrate JSF and Spring was to define JSF beans in faces-config as managed beans and refer to the spring beans using the managed-property configuration. With the help of the spring’s delegatingvariableresolver the managed property is resolved from spring application context and JSF’s IOC injects the bean to the JSF Managed bean instance. I’ve written an article it about this way before.First approach is modelled as follows

And the better approach described in this article

Although the way described above sounds nice at first glance, I believe it has a major issue, do we really need to have two IOC containers in your application to do dependency injection. I mean why not just one right? Actually this was necessary before spring 2 but with the addition of custom scopes, a better way for integration has come up. Now spring has the ability manage the JSF backing beans in it’s container, this results in a faces-config.xml with no managed-bean configurations. I’ve created a simple DVDStore application to show a sample configuration. Let’s start with the domain class DVD
01
package com.cc.blog.dvdstore.domain
02

03
public class DVD {
04

05
private String title;
06
private Integer discs;
07

08
public DVD() {
09

10
}
11

12
public DVD(String title, Integer discs) {
13
this.title = title;
14
this.discs = discs;
15
}
16

17
public Integer getDiscs() {
18
return discs;
19
}
20

21
public void setDiscs(Integer discs) {
22
this.discs = discs;
23
}
24

25
public String getTitle() {
26
return title;
27
}
28

29
public void setTitle(String title) {
30
this.title = title;
31
}
32

33
}
DVDService lives at service layer
1
package com.cc.blog.dvdstore.service;
2

3
import com.cc.blog.dvdstore.domain.DVD;
4

5
public interface IDVDService {
6

7
public void saveDVD(DVD dvd);
8

9
}

01
package com.cc.blog.dvdstore.service;
02

03
import com.cc.blog.dvdstore.domain.DVD;
04

05
public class DVDService implements IDVDService{
06

07
public void saveDVD(DVD dvd) {
08
//Refer to a DAO or repository implementation and persist the DVD
09
}
10

11
}

And the JSF Backing to handle the creation of a new DVD record
01
package com.cc.blog.dvdstore.view;
02

03
import com.cc.blog.dvdstore.domain.DVD;
04
import com.cc.blog.dvdstore.service.DVDService;
05

06
public class SaveDVDBean {
07

08
private DVD dvd;
09
private IDVDService service;
10

11
public SaveDVDBean() {
12
//NOop
13
}
14

15
public DVD getDvd() {
16
if(dvd == null)
17
dvd = new DVD();
18

19
return dvd;
20
}
21

22
public void setDvd(DVD dvd) {
23
this.dvd = dvd;
24
}
25

26
public IDVDService getService() {
27
return service;
28
}
29

30
public void setService(IDVDService service) {
31
this.service = service;
32
}
33

34
public String save() {
35
service.saveDVD(dvd);
36

37
return null;
38
}
39

40
}
Fragment from the JSF page backed by SaveDVDBean,
01

02

03

04

05

06

07

08

09

10

web.xml
01

02
03
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
04

05

06
contextConfigLocation
07
/WEB-INF/applicationContext.xml
08

09

10

11
org.springframework.web.context.ContextLoaderListener
12

13

14
org.springframework.web.context.request.RequestContextListener
15

16

17

18
Faces Servlet
19
javax.faces.webapp.FacesServlet
20
1
21

22

23
Faces Servlet
24
*.jsf
25

26

applicationContext.xml
01

02
03
xmlns:tx="http://www.springframework.org/schema/tx"
04
default-autowire="byName"
05
xsi:schemaLocation="
06
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
07
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
08
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
09

10

11

12

13

14

15

16

17


faces-config.xml
01

02
03

04
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
05

06

07
org.springframework.web.jsf.DelegatingVariableResolver
08

09

10

As seen above, faces-config has no managed-bean stuff, instead saveDVDBean is defined in spring’s application context in request scope. So here is why using Spring’s IOC to manage JSF backing beans is cool:)
- With spring aop, you can apply aop tricks to your jsf beans, for example you can do aop audit logging based on jsf events like SaveDVDBean’s save method. Add an annotation like @Auditable to the save() method, write an interceptor and then you can log who and when tried to save a dvd.
- Use autowiring on JSF beans
- Constructor Injection
- Lifecycle events like afterPropertiesSet using lifecycle interfaces or configurations like init-method, destroy-method
- Much more actually, see spring ioc container documents for more.

No comments: