根据控制代码质量的工具,JavaSpringbean不是线程安全的
在一个用@Service注释的Springbean中,我们使用@Autowired注释注入接口IConfigurationService。此接口由ConfigurationService bean实现。 根据控制代码质量的工具,ConfigurationService bean不是线程安全的。 此工具建议我们定义一个构造函数,用于初始化ConfigurationService的两个字段的值:“partConfigGacsiPath”和“partConfigMegPath”。 但当我看我们的代码时,已经有一个构造函数在做这样的事情了。使bean线程安全的代码中缺少什么
package com.myCompany.canalnet.gacsi.wspl.service.configuration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.myCompany.canalnet.wcm.exception.WCMException;
import com.myCompany.canalnet.wcm.mapper.IConfigXMLMapper;
import com.myCompany.canalnet.common.core.logging.CoreAlert;
import com.myCompany.canalnet.common.core.logging.CoreMarkers;
import com.myCompany.canalnet.common.core.logging.ErrorMessage;
import com.myCompany.canalnet.gacsi.common.core.ErrorCode;
import com.myCompany.canalnet.gacsi.wspl.service.configuration.bean.ConfigurationGacsi;
import com.myCompany.canalnet.gacsi.wspl.service.configuration.bean.ConfigurationMeg;
@Service
public class ConfigurationService implements IConfigurationService {
/**
* The logger
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationService.class);
/**
* Message if error when reading configuration file
*/
private static final String ERROR_CONF_XML = "Error when getting back XML configuration file";
/**
* Mapper of the configuration files
*/
@Autowired
private transient IConfigXMLMapper configXMLMapper;
private transient String partConfigGacsiPath;
private transient String partConfigMegPath;
/**
* Constructor with initialization of the config paths
*/
public ConfigurationService() {
initConfigPaths();
}
/**
* Initializes the paths to the conf_main.xml of the application
*/
private void initConfigPaths() {
try {
final ResourceBundle resource = ResourceBundle.getBundle("configuration");
partConfigGacsiPath = resource.getString("configuration.gacsi.publication.part");
partConfigMegPath = resource.getString("configuration.meg.publication.part");
} catch (final MissingResourceException e) {
CoreAlert.traceAlert("411","Bundle not found");
LOGGER.error(CoreMarkers.CONFIG, ErrorMessage.slf4jFormat("Bundle not found", ErrorCode.BUNDLE_NOT_FOUND.getCode()), e);
}
}
/**
* {@inheritDoc}
*/
@Override
public ConfigurationGacsi getConfigurationGacsi(final HttpServletRequest request) {
ConfigurationGacsi configurationGacsi = null;
try {
configurationGacsi = configXMLMapper.loadConfigXML(partConfigGacsiPath, ConfigurationGacsi.class);
} catch (final WCMException e) {
CoreAlert.traceAlert("415", ERROR_CONF_XML);
LOGGER.error(CoreMarkers.BUSINESS, ErrorMessage.slf4jFormat(ERROR_CONF_XML, ErrorCode.CONF_NOT_FOUND), e);
}
return configurationGacsi;
}
/**
* {@inheritDoc}
*/
@Override
public ConfigurationMeg getConfigurationMeg(final HttpServletRequest request) {
ConfigurationMeg configurationMeg = null;
try {
configurationMeg = configXMLMapper.loadConfigXML(partConfigMegPath, ConfigurationMeg.class);
} catch (final WCMException e) {
CoreAlert.traceAlert("415", ERROR_CONF_XML);
LOGGER.error(CoreMarkers.BUSINESS, ErrorMessage.slf4jFormat(ERROR_CONF_XML, ErrorCode.CONF_NOT_FOUND), e);
}
return configurationMeg;
}
public final void setConfigXMLMapper(final IConfigXMLMapper configXMLMapper) {
this.configXMLMapper = configXMLMapper;
}
}
# 1 楼答案
重要的是不要让
this
去“转义”,这意味着不要让实例被传递到另一种“进程”原因是当private获取实例时,您的实例可能没有完全初始化,这可能会导致一些不一致
但乍一看这里似乎是
OK