Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dependency injection 分层体系结构中的CDI。如何使用CDI注释注入服务对象?_Dependency Injection_Jsf 2_Layer_Cdi - Fatal编程技术网

Dependency injection 分层体系结构中的CDI。如何使用CDI注释注入服务对象?

Dependency injection 分层体系结构中的CDI。如何使用CDI注释注入服务对象?,dependency-injection,jsf-2,layer,cdi,Dependency Injection,Jsf 2,Layer,Cdi,我正在开发一些应用程序,它由三层组成: 数据库访问层(JPA+Hibernate作为提供程序) 业务逻辑层 表示层(JSF2.0) 在开始之前,我已经阅读了DavidGeary和CayS.Horstmann的《核心JavaServerFaces》(第三版)一书中的一些章节。在本书中,作者强烈建议使用@Named注释而不是@ManagedBean。好的,我想我可以试试 然后,我通过实现一些基本功能(用户登录)继续构建我的应用程序 我还阅读了一些新的注释,即@Inject。我认为仅仅基于接口将一个层

我正在开发一些应用程序,它由三层组成:

  • 数据库访问层(JPA+Hibernate作为提供程序)
  • 业务逻辑层
  • 表示层(JSF2.0)
  • 在开始之前,我已经阅读了DavidGeary和CayS.Horstmann的《核心JavaServerFaces》(第三版)一书中的一些章节。在本书中,作者强烈建议使用
    @Named
    注释而不是
    @ManagedBean
    。好的,我想我可以试试

    然后,我通过实现一些基本功能(用户登录)继续构建我的应用程序

    我还阅读了一些新的注释,即
    @Inject
    。我认为仅仅基于接口将一个层注入另一个层是非常舒服的。但是我恐怕我误解了什么,所以我带着我的问题来找你

    让我介绍我的代码的一些部分:

    CredentialsBean.java

    @Named("userCredentials")
    public class CredentialsBean {
        @Inject
        AccountService accountService;
    
        private String login;
        private String password;
    
        public String verify()
        {
            if (accountService.verifyCredentials(login, password))
                return "success";
            else
                return "failure";
        }
        // getters and setters
    }
    
    public interface AccountService {
        public Boolean verifyCredentials(String login, String password);
    }
    
    public interface AccountDAO {
        public Account getAccount(String login);
    }
    
    public class AccountDAOImpl implements AccountDAO {
        @PersistenceContext(unitName = "MyApp")
        protected EntityManager em;
    
        public EntityManager getEntityManager() {
            return em;
        }
    
        @Override
        public Account getAccount(String login) {
            // some data processing
        }
    }
    
    AccountService.java

    @Named("userCredentials")
    public class CredentialsBean {
        @Inject
        AccountService accountService;
    
        private String login;
        private String password;
    
        public String verify()
        {
            if (accountService.verifyCredentials(login, password))
                return "success";
            else
                return "failure";
        }
        // getters and setters
    }
    
    public interface AccountService {
        public Boolean verifyCredentials(String login, String password);
    }
    
    public interface AccountDAO {
        public Account getAccount(String login);
    }
    
    public class AccountDAOImpl implements AccountDAO {
        @PersistenceContext(unitName = "MyApp")
        protected EntityManager em;
    
        public EntityManager getEntityManager() {
            return em;
        }
    
        @Override
        public Account getAccount(String login) {
            // some data processing
        }
    }
    
    AccountServiceImpl.java:

    AccountDAO.java

    @Named("userCredentials")
    public class CredentialsBean {
        @Inject
        AccountService accountService;
    
        private String login;
        private String password;
    
        public String verify()
        {
            if (accountService.verifyCredentials(login, password))
                return "success";
            else
                return "failure";
        }
        // getters and setters
    }
    
    public interface AccountService {
        public Boolean verifyCredentials(String login, String password);
    }
    
    public interface AccountDAO {
        public Account getAccount(String login);
    }
    
    public class AccountDAOImpl implements AccountDAO {
        @PersistenceContext(unitName = "MyApp")
        protected EntityManager em;
    
        public EntityManager getEntityManager() {
            return em;
        }
    
        @Override
        public Account getAccount(String login) {
            // some data processing
        }
    }
    
    AccountDAOImpl.java

    @Named("userCredentials")
    public class CredentialsBean {
        @Inject
        AccountService accountService;
    
        private String login;
        private String password;
    
        public String verify()
        {
            if (accountService.verifyCredentials(login, password))
                return "success";
            else
                return "failure";
        }
        // getters and setters
    }
    
    public interface AccountService {
        public Boolean verifyCredentials(String login, String password);
    }
    
    public interface AccountDAO {
        public Account getAccount(String login);
    }
    
    public class AccountDAOImpl implements AccountDAO {
        @PersistenceContext(unitName = "MyApp")
        protected EntityManager em;
    
        public EntityManager getEntityManager() {
            return em;
        }
    
        @Override
        public Account getAccount(String login) {
            // some data processing
        }
    }
    
    最后一个类在一些带有
    @Entity
    注释的Java类上操作,无需担心

    我觉得我的解决方案有问题

    基本的错误是,即使我向使用
    标记创建的表单提供了一些数据,在调试
    verify()
    方法时,我可以看到,
    login
    password
    都是
    null
    ,所以这里有些错误,但我不知道是什么

    我还担心我是否理解
    @Inject
    很好。我可以像上面提供的那样使用它来使用接口耦合层吗


    嗯。我找到了登录和密码字段为空的原因,但我还不知道解决方案。 之所以发生这种情况,是因为在以某种神奇的方式执行期间,创建了多个(至少两个)CredentialsBean实例。签入Eclipse调试器。第一个字段设置正确,但第二个字段设置不正确,第二个字段的值被发送到服务层。
    我想知道这是否不是一个范围问题。我不应该把@SessionScoped放在CredentialsBean中吗?

    你对
    @Inject
    的理解是正确的,这正是它的目的。您的注入点很可能是空的,因为您没有bean存档(您需要在WEB-INF或META-INF中有一个名为beans.xml的文件,如果它是jar,它可以是空的)。这是在注入点中使用null的常见原因。

    我认为问题在于CredintialsBean类。您没有为bean指定作用域,因此它使用默认作用域(有关更多信息,请参阅)


    如果向类中添加类似@RequestScoped的内容,它应该可以工作。确保您使用的是javax.enterprise.context.RequestScoped,而不是javax.faces版本。

    您的实现类没有
    @Named
    注释。这是故意的还是过于简化了代码片段?他们必须这样做吗?我认为只有用于在JSF页面和应用程序逻辑之间传输信息的bean才需要它。我错了吗?
    @Stateless
    如果它应该是一个EJB,那么它也可以。容器还应该如何知道您有哪些实现以及需要注入哪些实现?我不理解您的回答。我想我不需要EJB。我创建层是为了允许不同的对象使用服务层,即JSFbean执行一些任务,HttpServlet执行另一些任务。我不认为我需要EJB组件,只是
    AccountDAOImpl
    是一个典型的
    @无状态
    EJB实现。如果您想将其命名为
    ,可以,但您必须自己管理事务。但这并不是我评论的真正目的。关键是,如果您不注释实现,容器如何知道您有哪些实现以及需要注入哪些实现?不幸的是,这不是正确的解决方案。从eclipse项目配置开始,WebContent/WEB-INF目录中就有beans.xml。我的登录名和密码仍然为空。有什么想法吗?我不明白你怎么会得到空值而不是异常。