【发布时间】:2012-01-04 03:13:58
【问题描述】:
我正在开发一些应用程序,它由三层组成:
- 数据库访问层(JPA + Hibernate 作为提供者)
- 业务逻辑层
- 表示层 (JSF 2.0)
在开始之前,我阅读了 David Geary 和 Cay S. Horstmann 所著的 Core JavaServer Faces (3rd Edition) 一书中的一些章节。在本书中,作者强烈推荐使用@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
}
AccountService.java:
public interface AccountService {
public Boolean verifyCredentials(String login, String password);
}
AccountServiceImpl.java:
public class AccountServiceImpl implements AccountService {
@Inject
AccountDAO dao;
@Override
public Boolean verifyCredentials(String login, String password) {
// some logic
}
}
AccountDAO.java:
public interface AccountDAO {
public Account getAccount(String login);
}
AccountDAOImpl.java:
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 类上运行,没关系。
我感觉我的解决方案有问题。
基本错误是事实,即使我向使用<h:form>、<h:inputText> 标签创建的表单提供一些数据,在调试verify() 方法时我可以看到login 和password 是@987654335 @,所以这里出了点问题,但我不知道是什么。
我也担心我是否理解@Inject。我可以像上面提供的那样使用它来使用接口耦合层吗?
好的。我找到了登录和密码字段为空的原因,但我还不知道解决方案。 这是因为在以某种神奇的方式执行期间,创建了多个(至少两个)CredentialsBean 实例。在 Eclipse 调试器中检查。第一个正确设置其字段,但第二个没有,第二个的值被发送到服务层。 我想知道这是否不是范围问题。我不应该将@SessionScoped 放在 CredentialsBean 中吗?
【问题讨论】:
-
您的实现类没有
@Named注释。这是对代码 sn-ps 的故意还是过度简化? -
他们必须这样做吗?我认为只有用于在 JSF 页面和应用程序逻辑之间传输信息的 bean 才需要它。我错了吗?
-
@Stateless如果应该是 EJB 也可以。容器应该如何知道您拥有和需要注入哪些实现? -
我不明白你的回复。我想我不需要EJB。我创建层是为了允许不同的对象使用服务层,即 JSF bean 执行一些任务,而 HttpServlet 执行一些其他任务。我不相信我需要 EJB 组件。
-
只是
AccountDAOImpl是一个典型的@StatelessEJB实现。如果你想成为@Named,很好,但你必须自己管理交易。但这不是我的评论的真正意义所在。关键是,如果你不注释实现,容器应该如何知道你拥有和需要注入哪些实现?
标签: dependency-injection jsf-2 layer cdi