Java Spring可缓存异步更新,同时返回旧缓存
还有rest控制器,它从Java Spring可缓存异步更新,同时返回旧缓存,java,spring,spring-boot,spring-cache,Java,Spring,Spring Boot,Spring Cache,还有rest控制器,它从@Service调用@Cacheable方法。我的CacheManager有expireAfterWrite超时,所以在超时后使用rest->service方法时,必须重写缓存。但问题是,如果同时有许多rest调用,则所有调用的线程都会转到服务方法并重写缓存。我需要通过@Cacheable(sync=true)进行服务方法同步,但其他调用必须在第一次调用创建新缓存时返回旧缓存 package application.system.config; import com.g
@Service
调用@Cacheable
方法。我的CacheManager
有expireAfterWrite
超时,所以在超时后使用rest->service方法时,必须重写缓存。但问题是,如果同时有许多rest调用,则所有调用的线程都会转到服务方法并重写缓存。我需要通过@Cacheable(sync=true)
进行服务方法同步,但其他调用必须在第一次调用创建新缓存时返回旧缓存
package application.system.config;
import com.google.common.cache.CacheBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
public class CacheManagerConfiguration {
@Value("${cache.timer.timeout}")
private int cacheTimeout;
@Bean("timeOutCacheManager")
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager() {
@Override
protected Cache createConcurrentMapCache(String name) {
return new ConcurrentMapCache(
name,
CacheBuilder.newBuilder()
.expireAfterWrite(cacheTimeout, TimeUnit.SECONDS)
.build().asMap(), false);
}
};
}
}
@GetMapping(RestEndpoints.GET\u计划)
公共响应getSchedule(@RequestParam(required=false)字符串部门,
@RequestParam(required=false)长组)抛出InterruptedException{
返回ResponseEntity.ok(scheduleService.getSummaryReport(部门、组));
}
@Transactional
@可缓存(值=Caches.SUMMARY_报告,条件=“#root.target.isCacheEnable”,sync=true)
公共摘要报告getSummaryReport(字符串部门,长组){
SummaryReport=新的SummaryReport(){{
setDepartments(新ArrayList());
}};
列出部门实体=getDepartmentsData(部门);
List scheduleEntities=getSchedulesData(部门、组);
列表约束性=getConstraintsData(部门、组);
部门实体。forEach(部门实体->{
列出部门计划=计划实体
.stream()
.filter(schedule->schedule.getEnable()==1)
.filter(schedule->schedule.getDepartmentTableRef().getId().equals(departmentEntity.getId()))
.collect(Collectors.toList());
列出部门constraintEntities=constraintEntities
.stream()
.filter(实体->实体.getDepartmentTableRef().getId().equals(departmentEntity.getId()))
.collect(Collectors.toList());
reportHandler.addDepartmentToReport(报告、部门实体、部门计划、部门约束实体);
});
info(“缓存已过期,实际数据由{}获取,”,getCurrentApp());
返回报告;
}
@GetMapping(RestEndpoints.GET_SCHEDULE)
public ResponseEntity<SummaryReport> getSchedule(@RequestParam(required = false) String department,
@RequestParam(required = false) Long group) throws InterruptedException {
return ResponseEntity.ok(scheduleService.getSummaryReport(department, group));
}
@Transactional
@Cacheable(value = Caches.SUMMARY_REPORT, condition = "#root.target.isCacheEnable", sync = true)
public SummaryReport getSummaryReport(String department, Long group) {
SummaryReport report = new SummaryReport() {{
setDepartments(new ArrayList<>());
}};
List<DepartmentTable> departmentEntities = getDepartmentsData(department);
List<ScheduleTable> scheduleEntities = getSchedulesData(department, group);
List<ConstraintTable> constraintEntities = getConstraintsData(department, group);
departmentEntities.forEach(departmentEntity -> {
List<ScheduleTable> departmentsSchedules = scheduleEntities
.stream()
.filter(schedule -> schedule.getEnable() == 1)
.filter(schedule -> schedule.getDepartmentTableRef().getId().equals(departmentEntity.getId()))
.collect(Collectors.toList());
List<ConstraintTable> departmentsConstraintsEntities = constraintEntities
.stream()
.filter(entity -> entity.getDepartmentTableRef().getId().equals(departmentEntity.getId()))
.collect(Collectors.toList());
reportHandler.addDepartmentToReport(report, departmentEntity, departmentsSchedules, departmentsConstraintsEntities);
});
LOGGER.info("Caches were expired, actual data was obtained by {}", getCurrentApp());
return report;
}