【问题标题】:Why @Singleton over @ApplicationScoped in Producers?为什么在 Producers 中使用 @Singleton 而不是 @ApplicationScoped?
【发布时间】:2015-01-22 02:05:45
【问题描述】:

LoggerProducer.java 是一个用于生成要注入到 CDI bean 中的 Logger 的类:

@Inject 
Logger LOG;

完整代码:

import javax.ejb.Singleton;

/**
 * @author rveldpau
 */
@Singleton
public class LoggerProducer {

    private Map<String, Logger> loggers = new HashMap<>();

    @Produces
    public Logger getProducer(InjectionPoint ip) {
        String key = getKeyFromIp(ip);
        if (!loggers.containsKey(key)) {
            loggers.put(key, Logger.getLogger(key));
        }
        return loggers.get(key);
    }

    private String getKeyFromIp(InjectionPoint ip) {
        return ip.getMember().getDeclaringClass().getCanonicalName();
    }
}

问题@Singleton 可以安全地变成@ApplicationScoped 吗?

我的意思是,为什么有人要在这里使用 EJB?是否有技术原因,因为不涉及任何事务,并且(AFAIK)无论如何它都是线程安全的?

我显然指的是javax.enterprise.context.ApplicationScoped,而不是javax.faces.bean.ApplicationScoped

【问题讨论】:

  • HashMap 不是线程安全的
  • @SME_Dev 当然,我的错误是认为@ApplicationScoped 是,谢谢你的评论顺便说一句
  • @AndreaLigios 你能澄清一下你的问题是关于javax.ejb.Singleton还是javax.inject.Singleton
  • @johnament javax.ejb.Singleton
  • 导入在这里非常重要。 inject 的单例没有 EJB 的单例的品质。

标签: java jakarta-ee thread-safety cdi ejb-3.1


【解决方案1】:

@Singleton 注释不仅提供事务,而且默认提供线程安全。因此,如果您将其替换为@ApplicationScoped,您将失去同步。因此,为了使其正确,您需要这样做:

@ApplicationScoped
public class LoggerProducer {

   private final ConcurrentMap<String, Logger> loggers = new ConcurrentHashMap<>();

   @Produces
   public Logger getProducer(InjectionPoint ip) {
      String key = getKeyFromIp(ip);
      loggers.putIfAbsent(key, Logger.getLogger(key));
      return loggers.get(key);
   }

   private String getKeyFromIp(InjectionPoint ip) {
     return ip.getMember().getDeclaringClass().getCanonicalName();
  }
}

如果你将地图设为静态,你也可以完全没有任何范围

【讨论】:

  • 水晶般清澈。我记错了@ApplicationScoped 也是线程安全的,结果证明这是错误的。想一想,这绝对是一致的:所有 EJB 都是线程安全的,所有 CDI bean 都不是,这个范围也不例外。感谢您的回答
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2013-04-12
  • 2017-10-11
  • 2014-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多