Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Разъясните про бины


Автор: zhz 11.2.2013, 03:43
Окончательно запутался в бинах. Объясните пожалуйста на конкретном примере. 
Делаю  no-interface Stateless Session Bean. (Он же backing bean, так? )
Код

package local.beans;

import javax.annotation.PostConstruct;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;

@LocalBean
@Stateless
public class PrivetBean {
    private String privet ;

    public PrivetBean() {

    }

    @PostConstruct
    public void init() {
        privet = "Initial Privet";
    }

    public String getPrivet() {
        return privet;
    }

    public void setPrivet(String privet) {
        this.privet = privet;
    }


}

Делаю контроллер, он же ManagedBean. Данный ManagedBean при помощи аннотации @EJB через CDI инжектирует в себя предыдущий no-interface Stateless Session Bean.
Код



package local.beans;

import local.utils.StringUtility;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.logging.Logger;

//@Named
@ManagedBean
@RequestScoped


public class MainViewBean {
    private static final Logger logger =  Logger.getLogger("local.beans.MainSampleViewBean");


    @EJB
    //@Inject
    private PrivetBean privetBean;

    private  String sampleString = "default string";

    public void setSampleString(String sampleString) {
        this.sampleString = sampleString;
    }

    public String getSampleString() {
        return sampleString;
    }

    public MainViewBean() {
    }

    public void doPrivet() {

        privetBean.setPrivet(StringUtility.toUpperCase(privetBean.getPrivet()));
        sampleString = StringUtility.toUpperCase(sampleString);
        logger.warning("--------------------------sampleString" + sampleString);
        logger.warning("--------------------------privetBean.privet" + privetBean.getPrivet());

    }

    public PrivetBean getPrivetBean() {

        return privetBean;
    }

    public void setPrivetBean(PrivetBean privetBean) {
        this.privetBean = privetBean;
    }
}


И последнее, есть view в виде JSF:
Код



<h:head>

</h:head>

<h:body>
    <h:form id="greetme">
        <p:inputText value="#{mainViewBean.privetBean.privet}" />
        <br/>
        <p:inputText value="#{mainViewBean.sampleString}" />
        <br/>
<p:commandButton value="do" action="#{mainViewBean.doPrivet}"/>
        <br/>
        <h:outputText value="#{mainViewBean.privetBean.privet}"/> <!-- после нажатия кнопки, ничего не меняется на странице -->
        <br/>
        <h:outputText value="#{mainViewBean.sampleString}"/>       <!-- после нажатия кнопки, ничего не меняется на странице -->
</h:form>
</h:body>

</html>

Данное приложение работает как и ожидается за исключением отображения переменных (пометил в коде) после нажатия на кнопку. Т.е. в логах сервера я вижу, что значение переменных меняется, но на странице не отображается. Почему?? 

Самое непонятное, - если я комментирую @ManagedBean, и вместо нее оставляю @Named, что от этого меняется? Бин перестает быть Managed Bean?  Теперь я должен производить инъекцию первого бина путем @Inject (вместо @EJB). В чем разница этих подходов? И главное, ПОЧЕМУ, во втором случае(использование @Named  и @Inject), после нажатия кнопки изменяется только  mainViewBean.privetBean.privet, а mainViewBean.sampleString остается без изменений?! Как так!?

Автор: korian 11.2.2013, 04:58
Для начала есть EJB, CDI, JSF.
Все они предоставляют возможность инъектов.
JSF в себе содержит почти все, что предостав CDI.

JSF:
@ManagedBean - анатация говорит, что бин - JSF бин. Он будет видет в EL по имени
Далье у JSF есть скоупы: @RequestScope, @ViewScope, @SessionScope (внимательно смотрите, когда импортите их, потому что у CDI такие же).
@ManagedProperty - анатация для инъектов. Возможность заинъектить другой объект. Будет работать только с JSF бинами, т.е. с теми где есть @ManagedBean.

CDI:
Впринципе любой класс, у которого есть default конструктор или для которого объявлен продюсер метот (@Produces) может быть как бы CDI бином.
@Named - бин будет виден в EL (но это не JSF бин)
Далье у CDI есть скоупы: @RequestScoped, @ConversationScoped, @SessionScoped, @ApplicationScoped (опять же внимательно при имортах)
@Inject - возможность инъектить. Работает как минимум с CDI и EJB бинами. С JSF вроде не работает.

EJB:
@Stateless, @Statefull, @Singletone - анатации говорят, что это EJB бин. В них будут доступны всякие вкусности EJB, аля работа с транзакциями, многопоточность и тп.
@EJB - возможность инъектить EJB бин. (можно использовать CDI @Inject вместо этого).


Ну а дальше вам надо разбираться в скоупах и времени жизни разных скоупов. Я думаю это проще нагуглить.

Автор: zhz 11.2.2013, 05:50
Спасибо, все начало становится на места. Только вот почему в приведенном коде, при использовании @Named не  присваивается значение через <h:outputText value="#{mainViewBean.sampleString}"/>   ?

Автор: korian 11.2.2013, 19:58
Возможно надо добавить RequestScoped?

Автор: zhz 21.2.2013, 01:57
Все верно, скоуп один и тот же, но у разных бинов разные импорты.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)