发出新请求时会保留 Springboot 组件状态。并发问题?
Springboot component state is kept when making new request.. Concurrency issue?
我有一个 SpringBoot 应用程序,它通过 @RestController 公开了一个简单的 REST-api。它需要一个文件上传,并尝试从上传的 excel 文件中读取值。
问题是某些组件的“状态”似乎没有根据新请求重置,就像某种并发问题一样。我似乎无法弄清楚。就像当我在第一个请求之后发出一个新的后续请求时,前一个请求的值仍然挂在 ImportProcessor 和后续对象中,它没有被重置,我不知道为什么..
应用程序的服务层@Autowires 一个“ImportProcessor”组件,它有很多字段可以通过它的方法修改。示例:
@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
}
这里是调用服务:
@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..
}
如果我不@Autowire ImportProcessor,它工作正常并且我没有并发问题。但是 ImportService 似乎绝对不可能调用 @Autowired DatabaseImporter,它是 CrudRepository 接口
如果我能确保 ImportProcessor 对每个新请求都有一个新的开始,一切都会按预期进行。我真的希望我能在这里得到一些提示。谢谢!
Spring 如果您没有指定 bean 范围,则引导基于单例模型,这意味着您在 @Autowired 时指定为 bean 的每个组件(@Component、@Service 或其他)组件无论在任何地方,它总是同一个实例,这就是为什么你的状态不会被重置。
希望这有助于回答您的问题。
我有一个 SpringBoot 应用程序,它通过 @RestController 公开了一个简单的 REST-api。它需要一个文件上传,并尝试从上传的 excel 文件中读取值。
问题是某些组件的“状态”似乎没有根据新请求重置,就像某种并发问题一样。我似乎无法弄清楚。就像当我在第一个请求之后发出一个新的后续请求时,前一个请求的值仍然挂在 ImportProcessor 和后续对象中,它没有被重置,我不知道为什么..
应用程序的服务层@Autowires 一个“ImportProcessor”组件,它有很多字段可以通过它的方法修改。示例:
@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
}
这里是调用服务:
@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..
}
如果我不@Autowire ImportProcessor,它工作正常并且我没有并发问题。但是 ImportService 似乎绝对不可能调用 @Autowired DatabaseImporter,它是 CrudRepository 接口
如果我能确保 ImportProcessor 对每个新请求都有一个新的开始,一切都会按预期进行。我真的希望我能在这里得到一些提示。谢谢!
Spring 如果您没有指定 bean 范围,则引导基于单例模型,这意味着您在 @Autowired 时指定为 bean 的每个组件(@Component、@Service 或其他)组件无论在任何地方,它总是同一个实例,这就是为什么你的状态不会被重置。
希望这有助于回答您的问题。