aftermethod="doAfter"pointcut="execution(*cn.itcast.core.service.*.*Service.add*(..))"/>
aftermethod="doAfter"pointcut="execution(*cn.itcast.core.service.*.*Service.update*(..))"/>
aftermethod="doAfter"pointcut="execution(*cn.itcast.core.service.*.*Service.delete*(..))"/>
aspect>
config>
3.2创建CacheInterceptor切面对象
位置
内容
准备
/**
*基于Springaop的切面对象
*处理切面有三种
*after
*before
*around
*@authorlx
*
*/
publicclassCacheInterceptor{
@Autowired
privateMemCachedClientmemCachedClient;
//缓存默认超时时间
privatestaticfinalintTIMEOUT=3600000;
生成唯一的Key策略
//生成Key策略
publicStringgetCacheKey(ProceedingJoinPointjp)throwsJsonGenerationException,JsonMappingException,IOException{
StringBuilderkey=newStringBuilder();
//cn.itcast.core.service.order.OrderServiceImpl+getOrderListWithPage+(OrderQueryorderQuery)
StringpackageName=jp.getTarget().getClass().getName();
StringmethodName=jp.getSignature().getName();
Object[]args=jp.getArgs();
//序列化
ObjectMapperom=newObjectMapper();
om.setSerializationInclusion(Inclusion.NON_NULL);
//创建字符串流
StringWriterstr=newStringWriter();
for(Objectarg:
args){
om.writeValue(str,arg);
}
key.append(packageName)
.append(".")
.append(methodName)
.append(".")
.append(str.toString());
returnkey.toString();
}
查询时切面方法
//查询时切面方法
publicObjectdoAround(ProceedingJoinPointjp)throwsThrowable{
System.out.println("进入了doAround");
//保存数据到Memcached中去
//memcached原理
//Mapmap=newHashMap();
//第一件事:
连接memcached服务器
if(memCachedClient.stats().isEmpty()){
System.out.println("memcached服务器没有开启或无法连接!
");
returnjp.proceed();
}
//第二件事:
存储时的Key值如何生成
//Key
//1:
要求不能出现重复
//2:
要有规则,在不存储的情况下,可以随时把我们存储起来的数据找出来
StringcacheKey=getCacheKey(jp);
//查看memcached服务器中有没有缓存的数据
if(null==memCachedClient.get(cacheKey)){
Objectproceed=jp.proceed();
memCachedClient.set(cacheKey,proceed,TIMEOUT);
}
returnmemCachedClient.get(cacheKey);
}
变更时切面方法
//更改时切面方法
publicvoiddoAfter(JoinPointjp){
Stringname=jp.getTarget().getClass().getName();
//cn.itcast.core.service.order.OrderServiceImpl
//add*update*delete*
//get*
//获取memcached中的所有Key
Mapkeys=MemCachedUtil.getKeySet(memCachedClient);
//Map遍历所有key
Set>entrySet=keys.entrySet();
for(Entryentry:
entrySet){
Stringkey=entry.getKey();
if(key.startsWith(name)){
memCachedClient.delete(key);
}
}
}
测试
1)测试Controller层访问Service层时,是否能进入切面对象
2)第一次查询时,通过打断点,可看到进入Service查询数据库数据,第二次查询时,通过打断点,可看到不再进入Service,而是去缓存服务器查数据
3)数据变更时,在Service方法后清除此数据库表对应的Service层所有查询时缓存下来的数据
4共享Session解决
4.1位置
4.2CacheSessionProvider提供类的内容
注入对象
/**
*采用Memcached来存储Session中的用户对象
*
*@authorlx
*
*/
publicclassCacheSessionProviderimplementsSessionProvider{
//注入MemachedClient
@Autowired
privateMemCachedClientmemCachedClient;
//设置一个Session超时时间
privateintsessionTimeout=30;//单位分钟
往Session中设置值
//往Session中设置值
publicvoidsetAttribute(HttpServletRequestrequest,Stringname,Serializablevalue){
//创建一个Map
Mapmap=newHashMap();
//装用户对象到map中
map.put(name,value);
//将Map发送到memached服务器中去
memCachedClient.set(getSessionId(request),map,sessionTimeout*60);//单位是秒
}
获取Session中的值
//获取Session中的值
@SuppressWarnings("unchecked")
publicSerializablegetAttribute(HttpServletRequestrequest,Stringname){
//从Memcached中取
Mapmap=null;
map=(Map)memCachedClient.get(getSessionId(request));
if(null!
=map){
returnmap.get(name);
}else{
returnnull;
}
}
退出登陆
//退出登陆
publicvoidlogout(HttpServletRequestrequest,HttpServletResponseresponse){
//让memcached中的数据失效
if(memCachedClient.keyExists(getSessionId(request))){
memCachedClient.delete(getSessionId(request));
}
}
获取SessionId
//获取SessionId
publicStringgetSessionId(HttpServletRequestrequest){
//JSESSIONID=2342141234asdfas
returnrequest.getRequestedSessionId();
}
4.3把CacheSessionProvider交给Spring实例类
位置
内容
--Session提供类-->
测试