简体   繁体   English

Springboot组件state在发出新请求时被保留..并发问题?

[英]Springboot component state is kept when making new request.. Concurrency issue?

I have a SpringBoot application which exposes a simple REST-api through @RestController.我有一个 SpringBoot 应用程序,它通过 @RestController 公开一个简单的 REST-api。 It takes a file upload, and attempts to read values from the uploaded excel file.它需要文件上传,并尝试从上传的 excel 文件中读取值。

The problem is that the "state" of some component does not seem to get reset on a new request, like it's some kind of concurrency issue.. I can't seem to figure it out.问题是某些组件的“状态”似乎没有在新请求上重置,就像它是某种并发问题一样。我似乎无法弄清楚。 Like when I make a new subsequent request after the first one, values from the previous request is still hanging in the ImportProcessor and subsequent objects, it's not getting reset and I cant figure out why..就像我在第一个请求之后发出新的后续请求时,前一个请求的值仍然挂在 ImportProcessor 和后续对象中,它没有被重置,我不知道为什么..

The service layer of the application @Autowires a "ImportProcessor" component, which has a lot of fields that are modified through it's methods.应用程序@Autowires 的服务层有一个“ImportProcessor”组件,它有很多通过它的方法修改的字段。 Example:例子:

@Component
@NoArgsConstructor
@Slf4j
public class ImportProcessor {

    public static STATE processState = STATE.READY;
    
    @Autowired
    RegulativImporter regulativImporter;

    @Autowired
    DatabaseImporter databaseImporter;

    Sheet strekning;
    Sheet strekning_periode;

    HashMap<Long, TakstkategoriEntity> successfulTakstkategori;
    HashMap<Long, RegulativEntity> successfulRegulativ;
    HashMap<Long, TakstEntity> successfulTakst;

        public ImportJobInfo handleStartProcessingRequest(Workbook workbook) throws FailedToStartProcessingException {
        if (processState == STATE.READY) {
            setProcessState(STATE.IMPORTING);
            ImportJobInfo importJobInfo = startProcessing(workbook);
            cleanUpState();
            return importJobInfo;
        } else {
            throw new FailedToStartProcessingException("Failed to start processing because of insufficient state:",
                processState);
        }
    }

   // Methods that modify and set these objects.. Changes state based on action, initialize hashMaps..
   // Method that inserts part of the Hashmaps to a database using DatabaseImporter
}

Here is the calling Service:这是调用服务:

@Service
@Slf4j
public class FergeregisterImportServiceImpl implements FergeregisterImportService {

    @Autowired
    ImportProcessor importProcessor;

    @Override
    public ImportJobInfo startImportJob(MultipartFile file) throws FailedToStartProcessingException {
        
        InputStream excelInputStream;
        Workbook workbook;
        ImportJobInfo importJobInfo = null;

        try {
            excelInputStream = file.getInputStream();
            workbook = new XSSFWorkbook(excelInputStream);
            log.info("Successfully converted Excel inputstream to Apache-POI workbook.");
        } catch (IOException e) {
            log.error(e.getMessage() + " | cause: " + e.getCause());
            throw new FailedToStartProcessingException("Failed to convert Excel inputstream to Apache-POI workbook.",
                STATE.FAILED);
        }

        try {
            importJobInfo = importProcessor.handleStartProcessingRequest(workbook);
        } catch (FailedToStartProcessingException e) {
            log.error(e.getMessage(), importProcessor.getProcessState());
            throw e;
        }

        return importJobInfo;
    }
   // Some other methods..
}

If I dont @Autowire the ImportProcessor, it works fine and I dont have the concurrency issues.如果我不@Autowire ImportProcessor,它可以正常工作并且我没有并发问题。 But then it seems absolutely impossible for the ImportService to call the @Autowired DatabaseImporter which is the CrudRepository interface但是,ImportService 似乎绝对不可能调用 CrudRepository 接口的@Autowired DatabaseImporter

If only I could make sure that the ImportProcessor had a fresh start on each new request, everything would work as intended.如果我能确保 ImportProcessor 对每个新请求都有一个新的开始,那么一切都会按预期工作。 I really hope I can get some tips here.我真的希望我能在这里得到一些提示。 Thank you!谢谢!

Spring Boot is based on Singleton model if you didn't specify the bean scope which means every component that you specify as bean (@Component, @Service or whatever-else) when you @Autowired that component no matter anywhere, it will always be that same instance and that is why your state is not reset. Spring Boot is based on Singleton model if you didn't specify the bean scope which means every component that you specify as bean (@Component, @Service or whatever-else) when you @Autowired that component no matter anywhere, it will always be同一个实例,这就是您的 state 未重置的原因。

Hope this help answer your question.希望这有助于回答您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM