Привет всем, меня зовут Сяои. Я полагаю, что все использовали аннотацию @Cacheable в Spring. Ее ключевой атрибут поддерживает выражения SPEL. Например, key="#root.args[0]" получает первый параметр метода, что значительно упрощает настройку ключа Cache.
Упомянутый выше SPEL (язык выражений Spring) — это язык выражений Spring, представленный в Spring 3.0. Он может собирать значения в свойства или конструкторы объектов посредством выражений, выполняемых программой во время выполнения.
Ранее компания Xiaoyi реализовала пользовательскую аннотацию кэша @CacheableTtl со сроком действия, но функция установки динамического значения ключа реализована путем добавления другой аннотации @CacheParam к входному параметру метода. Подробности смотрите в предыдущих статьях. Хотя @CachePram также поддерживает выражения SPEL, процесс реализации и использования по-прежнему не так прост и быстр, как @Cacheable.
На самом деле достаточно напрямую использовать SPEL. Я просто виню себя в том, что не умею учиться. Раньше я прошел большой круг.
В перехватчике получите имя параметра и сопоставление значений параметра во входных параметрах метода перехвата, а затем проанализируйте ключ выражения заклинания, чтобы получить значение ключа, фактически хранящееся в кеше.
@Component
@Aspect
public class CacheableAspect {
@Pointcut("@annotation(com.invent.momo.annotation.CacheableTtl)")
public void pointcut() {
}
@Around(value = "pointcut()")
public Object around(final ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();//Массив объектов входного параметра метода
Method method = MethodSignature.class.cast(pjp.getSignature()).getMethod();//Сущность метода
CacheableTtl cacheable = Method.getAnnotation(CacheableTtl.class);//сохранение
String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(метод);//имя параметра
StandardEvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < parameterNames.length; i++) {
context.setVariable(parameterNames[i], args[i]);
}
//Разбираем ключ выражения заклинания и получаем значение ключа, фактически хранящееся в кеше.
String key = parseSpelKey(cacheable, context);
//читаем кэш
Object value = getCache(cacheable, key);
if (null == value) {
value = pjp.proceed();//Метод выполнения
//Устанавливаем кеш
setCache(cacheable, key, value);
}
return value;
}
private String parseSpelKey(CacheableTtl cacheable, StandardEvaluationContext context) {
String keySpel = cacheable.key();
Expression expression = new SpelExpressionParser().parseExpression(keySpel);
String key = expression.getValue(context, String.class);
return key;
}
}
После установки перехватчика вы можете гибко настраивать выражения SPEL для пользовательских ключей аннотаций на уровне контроллера, точно так же, как при использовании ключей @Cacheable.
@RequestMapping("/com")
@RestController
public class ComController {
@CacheableTtl(key = "#demoUser.name + #demoUser.job", ttl = 5, ttlTimeUnit = TimeUnit.MINUTES)
@PostMapping("/summer")
public CustomVo summer(DemoUser demoUser) {
CustomVo customVo = new CustomVo();
customVo.setName(demoUser.getName() + demoUser.getJob());
return customVo;
}
@CacheableTtl(key = "'spring::' + #demoUser.name", ttl = 5, ttlTimeUnit = TimeUnit.MINUTES)
@PostMapping("/spring")
public CustomVo spring(DemoUser demoUser) {
CustomVo customVo = new CustomVo();
customVo.setName("xx");
return customVo;
}
@CacheableTtl(key = "#id + #name", ttl = 5, ttlTimeUnit = TimeUnit.MINUTES)
@PostMapping("/winter")
public CustomVo winter(@RequestParam("id") String id, @RequestParam("name") String name) {
CustomVo customVo = new CustomVo();
customVo.setAge("18");
customVo.setName(name);
return customVo;
}
}
Упомянутые выше исторические статьи могут быть прочитаны заинтересованными студентами. Добро пожаловать, подписывайтесь на публичный аккаунт Сяои и вместе изучайте новые знания.
Рекомендуемое чтение: