0
votes

Typically if I have to inject a service in Spring I use

 <bean id="mycontroller" class="com.MyController">
    <property name="myService" ref="myService" />

and

<bean id="myService" class="com.MyService"></bean>

How to do the same when using JSF? I dont want to use two IOC containers for the beans and rather keep it in faces context itself. I have seen links such as

JSF 2 inject Spring bean/service with @ManagedProperty and no xml

and A problem about injecting spring bean into jsf bean . They talk about injecting Spring managed bean into JSF context. What I am trying to do must be really simple but am not able to find any relevant info. Am a newbie and will appreciate any help.

2

2 Answers

6
votes

I think you may be confused by the word "bean". The thing is, the "service" you are talking about is also a Spring bean, right?

You probably have it as a service cause it has some additional features (probably transaction management) added by Spring, according to your configuration.

The JSF IoC container is very simplistic, it does not allow you to configure its lifecycle to include transaction management, AOP and things like that. Those things you have to do with Spring (or EJB, in a Java EE environment).

So, when using JSF with Spring, you usually have two choices:

  1. Either you put the backing beans for the JSF pages in the JSF container, annotating them with @ManagedBean, @RequestScoped, @ViewScoped, etc; and injecting any necessary Spring bean with @ManagedProperty in a property (a setter is required)
  2. Or skip the JSF container and put the backing beans along with all others in the Spring container, and use the Spring scopes of request/session, annotating them with Spring's annotations @Component, @Scope("request"), @Scope("session") and injecting with @Autowired, @Qualifier and the like.

Personally, faced with that choice I'd go with the first choice, cause it gives you @ViewScoped and some other niceties. It's true it makes use of two IoC containers but then, which Java EE app does not?

If you want to go the second route anyway, you may also add a view scope for Spring beans, backed by JSF viewMap.

2
votes

What Spring calls a "Service" is in Java EE terms an "EJB". EJB is out the box available in Java EE web profile containers like Glassfish, JBossAS and TomEE.

To create a stateless EJB service, just use @Stateless on the class:

@Stateless
public class SomeService {

    public void doSomething() {
        // ...
    }

}

And to inject it in a JSF managed bean, just use @EJB on the property-to-be-injected:

@ManagedBean
@ViewScoped
public class SomeController {

    @EJB
    private SomeService service;

}

That's it. No getter/setter necessary. No XML boilerplate necessary.