1

i want to use 2 different beans (Spring) for one JSF-Page. I do not like to write every method into one bean, so i tried to separate into two beans like JobEditDataBean and JobEditActionBean. I want to use the JobEdiDataBean just as "Container" for my data objects and move the actionstuff (like saving, update etc.) to the action bean. What i did by now (and what seems to work, but feels wrong) is the following:

public class JobEditDataBean{
    @Autowired
    JobEditActionBean actionBean;
    // some objects...
    @PostConstruct
    public void init() {
       actionBean.setJobEditDataBean(this);
       // do something ... 
    }
}

public class JobEditActionBean{
    JobEditDataBean dataBean;
    // some objects...
}

Do you have any hints or tipps how this can be done better, nicer?

djnose
  • 917
  • 7
  • 19
  • Uh? I usually have a "control" bean for web page (I saw somewhere it is recommended practice) but I can access other beans directly from JSF. For example, in my `ticket.xhtml` I mainly access `#{ticketCtrl.myMethod}`, but I can also use `#{userManager.getCurrentUserName()}` directly. – SJuan76 Sep 20 '12 at 08:59
  • thats true, but i would like to access the objects from `JobEditDataBean` in the `JobEditActionBean`. But this cannot be done, cause the `JobEditActionBean` does not know about the objects in `JobEditDataBean` – djnose Sep 20 '12 at 09:05

1 Answers1

1

Indeed, you don't need to have one bean per each page. You can use as much beans you want for any page, it is fine, as whenever an expression like #{someMB} is found in your XHTML, JSF will find a bean with that name and create a new instance if necessary.

If you need to inject one bean to another, just use @Autowired already:

@Component
@Scope("request")
public class JobEditActionBean {
    @Autowired
    private JobEditDataBean dataBean;
    @PostConstruct
    public void init() {
        // dataBean.youCanUseDataBeanMethodsHereAlready()
    }
}

You just have to make sure both beans are in the Spring container (annotating them with @Component will do), and choosing the right scope for each one. Beware of the scopes of the beans which you are injecting, cause it usually only makes sense to inject beans of broader scope to beans of the same or more restrict scope.

Having said that, I recommend reading following thread about choosing the right scopes:

How to choose the right bean scope?

One more thing: this is only valid if your JSF beans are really being managed by the Spring container (that was my assumption after you used @Autowired). If you are letting JSF container manage the beans (using @ManagedBean with @RequestScoped or @ViewScoped, for example), the way you inject them is with a @ManagedProperty annotation:

    ...
    @ManagedProperty("#{jobEditDataBean}")
    private JobEditDataBean dataBean;
Community
  • 1
  • 1
Elias Dorneles
  • 22,556
  • 11
  • 85
  • 107
  • Thx for your reply, but it does not answer my question, which is my fault, cause i did not explain it that well :). I am aware of using Scopes and different Beans etc. That what i want to do is: Share Data of a `DataBean` with an `ActionBean`. Like the `DataBean` just keeps the getter and setter and the objects, but the `ActionBean` can work with exact these data, without passing it to every function via parameter. I hope i could clearify my question somehow.... – djnose Sep 21 '12 at 08:28
  • Well, that's what I tried to say at the end. You just have to make sure that both beans are in the Spring container (annotating both with `@Component` with the proper `@Scope`, for example), and when you can use `@Autowired` to inject one in the other. But the answer is a bit confusing, sorry about that, I'll try to clarify. – Elias Dorneles Sep 21 '12 at 14:03
  • @djnose I've improved the answer, please see if it can help you now. Sorry for the previous mess. Thanks! – Elias Dorneles Sep 21 '12 at 14:25
  • No Problem, you should not say sry :). And Yes, you are right, i am using Spring. So can i just access the `DataBean` if i "only" @Autowire it to my `ActionBean`? And use it in my JSF Page like normal? f.e. i have `` and access this value in actionBean directly? like `actionBean.dataBean.value`? That would be just to easy :) i will try that! – djnose Sep 22 '12 at 10:19
  • @djnose Yes, you can do like that, but you will need the getter for `dataBean` if you want to access it through `actionBean`. Note that the instance is shared in the same request (or session, if that's the scope), so maybe it's best you can just refer directly to `dataBean` in your page. Good luck! :) – Elias Dorneles Sep 23 '12 at 15:24