【问题标题】:Which CDI scope should be used for DAO and Service classesDAO 和服务类应该使用哪个 CDI 范围
【发布时间】:2014-01-02 06:45:59
【问题描述】:

我正在尝试仅使用 JPA、CDI(OpenWebBeans + Deltaspike JPA 模块)、JSF 构建应用程序。我以与使用 Spring 框架相同的方式使用部署在 Tomcat 上的 CDI。我有这样的 DAO 称为 GenericDAOImpl(前几行):

public abstract class GenericDaoJpa<T> implements GenericDao<T> {
    private static final Log logger = LogFactory.getLog(GenericDaoJpa.class);

    @Inject
    protected EntityManager entityManager;

    private Class<T> type;

EntityManager 是使用 DeltaSpike JPA 模块 http://deltaspike.apache.org/jpa.html 注入的。然后,这个 GenericDao 由服务类使用的具体 DAO(UserDao 等)继承。

例如 UserServiceImpl:

public class UserServiceImpl implements UserService {

    private static final Log logger = LogFactory.getLog(UserServiceImpl.class);

    @Inject
    private UserDao userDao;

    @Transactional
    public void saveUser(UserDto user) throws UserServiceException {
        try {
            User u = new User(user);
            userDao.create(u);
        } catch (Exception e) {
            logger.error("Error while creating user.", e);
            throw new UserServiceException("Error while creating user.");
        }
    }
}

以这种方式使用 CDI,DAO 和 Service 类都将具有 Dependent 范围,这与 spring 中它们是单例的不同。因此每个客户端都会注入新的实例。 我应该将 DAO 和服务类的范围更改为 ApplicationScope 吗?但是按照规范,我必须使所有注入的类可序列化。如果是 Dao 类,这可能是个问题,EntityManager 应该被标记为瞬态吗?一个

如果有任何建议,我会很高兴。

【问题讨论】:

    标签: jakarta-ee jpa cdi


    【解决方案1】:

    @ApplicationScopedSerializable 无关,它们始终存在并且永远不会持久保存到磁盘。由于 HTTP 会话对象的行为,@SessionScoped 将需要序列化。

    我建议使用作用域,因为将所有内容都依赖会导致内存泄漏(删除 @Dependent 对象时永远不清楚)。如果您的应用程序相当无状态,您可以使用@RequestScoped@ApplicationScoped 您需要考虑多个客户端将连接到您的实例。

    【讨论】:

    • 感谢您的回答。如果我使用@ApplicationScoped,我希望像在Spring中一样,bean(在spring中的单例范围)将被同时访问很多次。因此不会有任何性能问题。我唯一关心的是使类线程安全。还是 CDI 容器不自动处理并发?
    • CDI 容器不处理并发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 2021-06-10
    • 2011-04-22
    • 2018-09-30
    • 2012-05-13
    • 2013-02-14
    • 1970-01-01
    相关资源
    最近更新 更多