切面注解
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface GmallCache {
String cacheKeyExpr() default "";
boolean enableBloom() default true;
String bloomName() default "";
long ttl() default -1L;
long missTtl() default -1L;
}
@GmallCache(
cacheKeyExpr = RedisConst.SKUKEY_PREFIX+"#{#args[0]}"+RedisConst.SKUKEY_SUFFIX,
enableBloom = true,
ttl = 60 * 1000 * 30, bloomName = BloomName.SKU, missTtl = 60 * 1000 * 10)
@Override
public Map<String, Object> getSkuInfo(Long skuId) {}
@Slf4j
@Component
@Aspect
public class GmallCacheAspect {
@Qualifier(BloomName.SKU)
@Autowired
RBloomFilter<Object> skuBloomFilter;
@Autowired
StringRedisTemplate stringRedisTemplate;
@Autowired
Map<String, RBloomFilter<Object>> blooms;
@Around("@annotation(com.atguigu.gmall.common.cache.GmallCache)")
public Object cacheAround(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
GmallCache gmallCache = signature.getMethod().getAnnotation(GmallCache.class);
String cacheKeyExpr = gmallCache.cacheKeyExpr();
String key = parseExpression(cacheKeyExpr, pjp);
boolean enableBloom = gmallCache.enableBloom();
String bloomName = gmallCache.bloomName();
long ttl = gmallCache.ttl();
long missTtl = gmallCache.missTtl();
String intern = key.intern();
Object cache = queryFromCache(key, method);
if (cache != null) {
log.info("缓存命中");
return cache;
}
try {
if (enableBloom) {
RBloomFilter<Object> bloomFilter = blooms.get(bloomName);
boolean contains = bloomFilter.contains(key);
if (!contains) {
log.info("布隆无此值");
return null;
}
}
if (cache == null) {
synchronized (intern) {
Object cacheAgain = queryFromCache(key, method);
if (cacheAgain == null) {
log.info("查询数据库");
Object proceed = pjp.proceed(args);
saveToCache(key, proceed, ttl, missTtl);
return proceed;
}
log.info("双检查缓存命中");
return cacheAgain;
}
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
}
return cache;
}
private String parseExpression(String cacheKeyExpr, ProceedingJoinPoint pjp) {
SpelExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression(cacheKeyExpr, new TemplateParserContext());
EvaluationContext context = new StandardEvaluationContext();
Object[] argsList = pjp.getArgs();
context.setVariable("args", argsList);
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
context.setVariable("method",method);
String value = expression.getValue(context, String.class);
return value;
}
private void saveToCache(String key, Object proceed, long ttl, long missTtl) throws JsonProcessingException {
}
public Object queryFromCache(String key, Method method) throws JsonProcessingException {
}
字段注解
1.实体类
public class SysUser
{
private Long[] roleIds;
}
public Long[] getRoleIds()
{
return roleIds;
}
public void setRoleIds(Long[] roleIds)
{
this.roleIds = roleIds;
}
2.反射
import com.fasterxml.jackson.annotation.JsonProperty;
public static Object getFieldValueByObject(Object object, String targetFieldName) throws Exception {
Class objClass = object.getClass();
Object result = null;
Field[] fields = objClass.getDeclaredFields();
for (Field field : fields) {
String currentFieldName = "";
try {
boolean has_JsonProperty = field.isAnnotationPresent(JsonProperty.class);
if (has_JsonProperty) {
currentFieldName = field.getAnnotation(JsonProperty.class).value();
} else {
currentFieldName = field.getName();
}
if (currentFieldName.equals(targetFieldName)) {
field.setAccessible(true);
result = field.get(object);
return result;
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return result;
}