gpt4 book ai didi

java - 为什么在生产者中使用 @Singleton 而不是 @ApplicationScoped?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:50:36 24 4
gpt4 key购买 nike

LoggerProducer.java是一个用于生成要注入(inject) CDI bean 中的记录器的类:

@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?是否存在技术原因,因为不涉及事务,并且(据我所知)无论如何它都是线程安全的?

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

最佳答案

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

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

关于java - 为什么在生产者中使用 @Singleton 而不是 @ApplicationScoped?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27103517/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com