Why is @Singleton over @ApplicationScoped in manufacturers?

LoggerProducer.java is a class used to create loggers that will be introduced into CDI beans using

@Inject Logger LOG; 

Full code:

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

QUESTION : Can @Singleton safely become @ApplicationScoped ?

I mean, why would anyone need EJB? Are there technical reasons because the transactions are not involved, and (AFAIK) would it be thread safe anyway?

I obviously mean javax.enterprise.context.ApplicationScoped , not javax.faces.bean.ApplicationScoped .

+5
source share
1 answer

@Singleton provides not only transaction, but also default thread safety. Therefore, if you replace it with @ApplicationScoped , you will lose synchronization. Therefore, to do this correctly, you need to do the following:

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

You can also do this completely without any area if you make the map static

+12
source

Source: https://habr.com/ru/post/1207575/


All Articles