为什么生产者中@Singleton优于@ApplicationScoped? [英] Why @Singleton over @ApplicationScoped in Producers?

查看:203
本文介绍了为什么生产者中@Singleton优于@ApplicationScoped?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

LoggerProducer.java 是用于生成要通过以下方式注入CDI bean的Logger的类:

LoggerProducer.java is a class used to produce Loggers to be injected in CDI beans with:

@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 吗?

QUESTION: can @Singleton be safely turned into @ApplicationScoped ?

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

I mean, why would anyone want an EJB here ? Are there technical reasons, since no transactions are involved, and (AFAIK) it would be thread-safe anyway ?

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

I'm obviously referring to javax.enterprise.context.ApplicationScoped, not to javax.faces.bean.ApplicationScoped.

推荐答案

默认情况下, @Singleton 注释不仅提供事务处理,而且还提供线程安全性。因此,如果将其替换为 @ApplicationScoped ,则会失去同步。因此,为了使其正确运行,您需要执行以下操作:

The @Singleton annotation provides not only transaction but also thread-safety by default. So if you will replace it with @ApplicationScoped, you will loose the synchronization. So in order to make it properly you need to do like this:

@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();
  }
}

如果您没有任何限制,也可以完全做到这一点将地图设为静态

Also you can make it completely without any scope if you make the map as static

这篇关于为什么生产者中@Singleton优于@ApplicationScoped?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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