SearchCacheAspect.java
5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.yoho.search.aop.cache;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.yoho.search.base.utils.MD5Util;
import com.yoho.search.cache.CacheType;
import com.yoho.search.cache.beans.SearchCacheFactory;
import com.yoho.search.cache.model.SearchCache;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.cache.beans.SearchCacheService;
@Component
@Aspect
@Order(Integer.MAX_VALUE-1)
public class SearchCacheAspect {
@Autowired
private SearchCacheService searchCacheService;
@Autowired
private SearchCacheFactory searchCacheFactory;
@Around("@annotation(com.yoho.search.aop.cache.SearchCacheAble)")
public Object doCache(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
// 检查注解
SearchCacheAble searchCacheAble = signature.getMethod().getAnnotation(SearchCacheAble.class);
if (searchCacheAble == null) {
return pjp.proceed();
}
// 检查返回类型
Class<? extends Serializable> returnClass = this.getReturnClass(searchCacheAble, signature);
if (returnClass == null) {
return pjp.proceed();
}
// 检查cacheKey
RedisKeyBuilder redisKeyBuilder = this.getRedisKeyBuilder(pjp, searchCacheAble);
if (StringUtils.isBlank(redisKeyBuilder.getKey())){
return pjp.proceed();
}
SearchCache searchCache = searchCacheFactory.getAspectSearhCache(searchCacheAble);
boolean useJsonSerializable = searchCacheAble.cacheType().equals(CacheType.EHCACHE)?false:true;
Serializable cacheObject = searchCacheService.getSerializableObjectFromCache(searchCache, redisKeyBuilder, returnClass,useJsonSerializable);
if (cacheObject != null) {
return cacheObject;
}
Object result = pjp.proceed();
if (result == null) {
return result;
}
cacheObject = (Serializable) result;
if (cacheObject instanceof SearchApiResult && ((SearchApiResult) cacheObject).getCode() != 200) {
return cacheObject;
}
searchCacheService.addSerializableObjectToCache(searchCache, redisKeyBuilder, cacheObject,useJsonSerializable);
return cacheObject;
}
// 校验返回类型是否一致
private Class<? extends Serializable> getReturnClass(SearchCacheAble searchCacheAble, MethodSignature signature) {
final Class<?> returnType = signature.getMethod().getReturnType();
final Class<? extends Serializable> returnClass = searchCacheAble.returnClass();
if (!returnType.getName().equals(returnClass.getName())) {
return null;
}
return returnClass;
}
// 获取请求的参数
private RedisKeyBuilder getRedisKeyBuilder(ProceedingJoinPoint pjp, SearchCacheAble searchCacheAble) {
Object[] arges = pjp.getArgs();
Object object = arges[0];
if (object instanceof ISearchCacheAbleParam) {
return this.getRedisKeyBuilder((ISearchCacheAbleParam) object, searchCacheAble);
}
if (object instanceof HttpServletRequest) {
return this.getRedisKeyBuilder((HttpServletRequest) object, searchCacheAble);
}
if (object instanceof Map) {
return this.getRedisKeyBuilder((Map<?, ?>) object, searchCacheAble);
}
return null;
}
// 获取SearchCacheAbleParam的缓存key
private RedisKeyBuilder getRedisKeyBuilder(ISearchCacheAbleParam searchCacheAbleParam, SearchCacheAble searchCacheAble) {
String valueString = searchCacheAbleParam.toCacheKeyValue();
return this.getRedisKeyBuilderByParamKey(valueString, searchCacheAble);
}
// 获取httpServletRequest的缓存key
private RedisKeyBuilder getRedisKeyBuilder(HttpServletRequest httpServletRequest, SearchCacheAble searchCacheAble) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(httpServletRequest);
return this.getRedisKeyBuilder(paramMap, searchCacheAble);
}
// 获取请求的参数
private RedisKeyBuilder getRedisKeyBuilder(Map<?, ?> paramMap, SearchCacheAble searchCacheAble) {
List<String> includeParams = Arrays.asList(searchCacheAble.includeParams());
List<String> excludeParams = Arrays.asList(searchCacheAble.excludeParams());
String paramKey = "";
if (!includeParams.isEmpty()) {
paramKey = HttpServletRequestUtils.genParamStringWithIncludeParams(paramMap, includeParams);
} else if (!excludeParams.isEmpty()) {
paramKey = HttpServletRequestUtils.genParamStringWithExcludeParams(paramMap, excludeParams);
} else {
paramKey = HttpServletRequestUtils.genParamString(paramMap);
}
return this.getRedisKeyBuilderByParamKey(paramKey, searchCacheAble);
}
private RedisKeyBuilder getRedisKeyBuilderByParamKey(String paramKey,SearchCacheAble searchCacheAble){
RedisKeyBuilder redisKeyBuilder = RedisKeyBuilder.newInstance();
redisKeyBuilder.appendFixed("YOHOSEARCH:AOP:");
redisKeyBuilder.appendFixed(searchCacheAble.cacheName()).appendFixed(":");
if(searchCacheAble.needMd5()){
redisKeyBuilder.appendVar(MD5Util.string2MD5(paramKey));
}else{
redisKeyBuilder.appendVar(paramKey);
}
return redisKeyBuilder;
}
}