Spring bean не является потокобезопасным в соответствии с инструментом, который контролирует качество нашего кода - PullRequest
0 голосов
/ 14 апреля 2020

В одном компоненте Spring, аннотированном с помощью @Service, мы внедряем интерфейс IConfigurationService с помощью аннотации @Autowired. Этот интерфейс реализуется компонентом ConfigurationService. Согласно инструменту, который контролирует качество нашего кода, компонент ConfigurationService не является потокобезопасным. Этот инструмент рекомендует нам определить конструктор, который инициализирует значения двух полей ConfigurationService: «partConfigGacsiPath» и «partConfigMegPath». Но когда я смотрю на наш код, уже один конструктор делает такую ​​вещь. Чего не хватает в нашем коде, чтобы сделать боб потокобезопасным?

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 Ответ

1 голос
/ 14 апреля 2020

Важно не допустить, чтобы this «сбежал», что означает не допустить передачи экземпляра другому типу «процесса».

Причина в том, что ваш экземпляр не может быть полностью инициализирован, когда частное лицо получает его, что может привести к некоторым несоответствиям.

Но на первый взгляд кажется, OK ..

...