Por que instanciação preguiçosa do MessageResourcesFactory no Struts 1.2.7?
-
19-09-2019 - |
Pergunta
Como existe o problema de bloqueio verificado duas vezes, precisamos usar a sincronização para garantir o acesso simultâneo ao seguinte método (org.apache.struts.util.messageSources Class):
Instanciação preguiçosa
public synchronized static MessageResources getMessageResources(String config) {
if (defaultFactory == null) {
defaultFactory = MessageResourcesFactory.createFactory();
}
return defaultFactory.createResources(config);
}
Por que não usar:
Instanciação ansiosa
static {
// Construct a new instance of the specified factory class
try {
if (clazz == null)
clazz = RequestUtils.applicationClass(factoryClass);
MessageResourcesFactory defaultFactory =
(MessageResourcesFactory) clazz.newInstance();
} catch (Exception e) {
LOG.error("MessageResourcesFactory.createFactory", e);
}
}
E depois:
public static MessageResources getMessageResources(String config) {
return defaultFactory.createResources(config);
}
Isso permitiria acesso simultâneo ao método getMessageSources, que pelo menos no meu caso pode ser chamado algumas vezes.
As implicações quando não estão usando sincronizadas estão aqui:
Solução 4
Eu acho que é uma maneira de os suportes garantir que funcione bem quando no modo multi-thread, não importa se a pessoa substituindo org.apache.struts.util.messageSources Define o createresources (configuração de string) como sincronizado ou não.
Outras dicas
É MessageResourcesFactory
discussão segura? o synchronized
o método protege a configuração do campo e o createResources
Chamada de método. Se for seguro, o bloqueio poderá ser movido para cobrir apenas definir o campo e deixar a chamada do método fora da seção crítica.
A sobrecarga incorrida por métodos sincronizados em uma JVM moderna é tão pequena que se torna insignificante. As chamadas subsequentes para o método sincronizado de fábrica de initação preguiçosas serão tão rápidas quanto as chamadas para um método não sincronizado.
Em termos de código, a abordagem de initação preguiçosa é mais simples e fácil de entender (na minha opinião) do que usar um bloco de inicializador estático. Além disso, quando os blocos estáticos do init falham, pode ser muito confuso descobrir onde e por quê.
A menos que haja alguma razão para MessageResourceFactory
Não pode ser inicializado desde o início (por exemplo, certos recursos do servlet precisam ser inicializados primeiro), acho que gosto mais da sua solução. Eu acho que não há razão para a equipe de struts carregar preguiçosamente a fábrica, exceto isso, é isso que o desenvolvedor em particular que trabalhou isso está acostumado a fazer (as pessoas tendem a carregar preguiçosamente singletons, mesmo quando não é necessário).
Você já tentou enviar um relatório de bug e propor sua solução?