对象的@Inject注释以及此对象的两种不同行为 [英] @Inject annotation for object and two different behaviors of this object

查看:46
本文介绍了对象的@Inject注释以及此对象的两种不同行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用JSF 2.2和CDI.我创建了以下示例,以向您展示我的问题的核心.您可以在下面看到:

I use a JSF 2.2 and CDI. I created below example to show you a heart of my problem. You can see below:

  • 两个xhtml页面,
  • 会话范围的CDI bean(LoginController),它是xhtml page1的控制器,
  • 视图作用域CDI bean(DataController),它是xhtml page2的控制器,
  • 请求范围的CDI bean(DataServiceImpl),它是DataController bean的服务.
  • the two xhtml pages,
  • the session scoped CDI bean (LoginController) which is the controller for the xhtml page1,
  • the view scoped CDI bean (DataController) which is controller for the xhtml page2,
  • the request scoped CDI bean (DataServiceImpl) which is the service for theDataController bean.

这是一个用例和数据流:

This is a use case and flow of the data:

xhtml page2-> DataController控制器->在send()方法(位于DataController类中)中调用dataService.addData()->执行addData()方法(位于DataServiceImpl中)课

xhtml page2 -> the DataController controller -> call dataService.addData() in send() method (which is located in the DataController class) -> execute addData() method (which is located in the DataServiceImpl class)

我的问题的核心:

  • 如果将LoginController注入到DataServiceImpl类中,则loginController对象不起作用(即,它返回null)[下面的代码中的选项1].
  • 如果将LoginController注入到DataController类中,则loginController对象可以正常工作(即,它返回我想要的内容)[下面的代码中的选项2].
  • If I inject the LoginController to the DataServiceImpl class, the loginController object doesn't work (i.e. it returns null) [Option 1 in the code below].
  • If I inject the LoginController to the DataController class, the loginController object works fine (i.e. it returns what I want) [Option 2 in the code below].

我的问题是:为什么这个注入的对象根据注入的位置以两种不同的方式表现?

My question is: Why this injected object behaves in two different ways depending on place of injection?

这是我的xhtml page1的一部分:

This is the part of my xhtml page1:

<h:form>               

    <p:growl id="growl" showDetail="false" />

    <h:inputText id="username" value="#{userLogin.username}" label="Username" required="true" requiredMessage="Username: This field is required." title="Enter your username." pt:placeholder="Username" />
    <h:inputSecret  id="password" value="#{userLogin.password}" label="Password" required="true" requiredMessage="Password: This field is required." title="Enter your password." pt:placeholder="Password" />
    <p:commandButton value="Login" action="#{loginController.login}" update="growl" />                  

</h:form>

这是我的xhtml page2的一部分:

This is the part of my xhtml page2:

<h:form>    

    <p:growl id="growl" showDetail="false" />

    <p:panelGrid id="panel" columns="2" styleClass="ui-noborder" columnClasses="rightalign,leftalign">
        <p:outputLabel for="data" value="Data:" />
        <p:inputText  id="data" value="#{data.text}" required="true" requiredMessage="Data: This field is required." />
        <p:commandButton id="buttonSend" value="Send" action="#{dataController.send()}" update="messages" />                        
    </p:panelGrid>                                              

</h:form>

这是会话范围的CDI bean:

This is the session scoped CDI bean:

@Named
@SessionScoped
public class LoginController implements Serializable {

    private static final long serialVersionUID = -6322113716363932422L;

    public String login(){      

        if(userService.login(userLogin)){

            currentUser=userService.getCurrnetUser(userLogin.getUsername());
            return "home?faces-redirect=true";          
        }
        else{

            facesContext.addMessage(null, new FacesMessage("Data entered are incorrect"));
            return null;
        }
    }

    public String logout(){

        currentUser=null;
        return "login?faces-redirect=true";
    }

    public boolean isLoggedIn() {

          return currentUser!=null;
    }

    @Produces
    @LoggedIn
    public UserAccount getCurrentUser(){

        return currentUser; 
    }   

    @Inject
    private FacesContext facesContext;

    @Inject
    private UserServiceImpl userService;

    @Named
    @Produces
    @RequestScoped
    private UserAccount userLogin=new UserAccount();

    private UserAccount currentUser;
}

这是视图范围内的CDI bean:

This is the view scoped CDI bean:

@Named
@ViewScoped
public class DataController implements Serializable {

    private static final long serialVersionUID = 1383572529241805730L;

    public void send(){

        /* OPTION 2
         * If I inject the LoginController here 
         * instead of in DataServiceImpl bean, the loginController object 
         * works fine (i.e. it isn't null and returns the name of the user). 
         */
        String name=loginController.getCurrentUser().getName();

        dataService=new DataServiceImpl();
        dataService.addData(data.getText);
    }

    @Named
    @Produces
    @RequestScoped
    private Data data=new Data();  

    @Inject
    private DataService dataService;

    @Inject
    private LoginController loginController;    
}

这是请求范围内的CDI bean:

This is the request scoped CDI bean:

@Named
@RequestScoped
public class DataServiceImpl implements DataService {

    @Override
    public void addData(String data) {

        /* OPTION 1
         * If I inject the LoginController here 
         * instead of DataController bean, the loginController object 
         * doesn't work (i.e. returns null. I get the NullPointerException exception 
         * in line below due to the loginController object which is null)
         */
        String name=loginController.getCurrentUser().getName();

        //Proccess some data
    }

    @Inject
    private LoginController loginController;
}

推荐答案

我不太了解您的设计,这可能是问题的一部分.

I don't really understand your design, and this may be part of the problem.

您不应将一个控制器注入另一个控制器,也不应将一个控制器注入服务.

You shouldn't inject a controller into another controller, or inject a controller into a service.

看到您的LoginController生成了@LoggedIn UserAccount,为什么不简单地注入它,而不是注入loginController并调用loginController.getCurrentUser().getName()?

Seeing that your LoginController produces a @LoggedIn UserAccount, why not simply inject that, instead of injecting the loginController and calling loginController.getCurrentUser().getName()?

这篇关于对象的@Inject注释以及此对象的两种不同行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆