spring AOP 抽取redis实例

1. 定义注解
package com.efoxconn.ipebg.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisValid {
	public String key() default "halfHour";
}


2. 创建处理类
package com.efoxconn.ipebg.common.util;

import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import com.efoxconn.ipebg.common.annotation.RedisValid;
/**
 * 抽取redis统一处理
 * 2016-11-25 17:57:31
 */
@Aspect
@Component
@SuppressWarnings({ "rawtypes", "unchecked" })
public class CacheAspect {
	@Resource
	private CacheUtil cacheUtil;
	// 定义切入点
	@Pointcut("execution(public * com.efoxconn.ipebg.protoline.service..*.*(..))")
	public void weavingRedis() { }
	// 环绕增强处理方法
	@Around("weavingRedis()")
	public Object weavingRedisCalls(ProceedingJoinPoint pjp) throws Throwable {
		// 得到目标方法的参数
		Object[] p = pjp.getArgs();
		List result = null;
		// 得到目标的class
		Class<?> clazz =  pjp.getTarget().getClass();
		// 得到目标方法的签名
		String methodName = pjp.getSignature().getName();
		String key = "";
		// 如果有参数,计算出key
		if (p != null && p.length > 0) {
			Map params = (Map) p[0];
			key = createKey(params, clazz.getSimpleName(), methodName);
		}else{
			key = clazz.getSimpleName() +  methodName;
		}
		// 先从redis中取值
		result = cacheUtil.getObject(key);
		// 如果redis中没有
		if (result == null||result.size() == 0) {
			// 放开去执行
			result = (List) pjp.proceed();
			String valid = "halfHour";
			// 得到注解的redis有效时长
	        MethodSignature msig = (MethodSignature) pjp.getSignature();
	        Method method = clazz.getMethod(methodName, msig.getParameterTypes());
			RedisValid redisValid = null;
			if(clazz.isAnnotationPresent(RedisValid.class)){
				redisValid=clazz.getAnnotation(RedisValid.class);
			}else if (method.isAnnotationPresent(RedisValid.class)) {
				redisValid=method.getAnnotation(RedisValid.class);
			}
			if (redisValid!=null) {
				valid = redisValid.key();
			}
			// 存redis
			cacheUtil.setObject(key, result, RedisValidConfig.getRedisValid(valid));
		}

		return result;
	}
	// cacheUtil中的原有计算key的逻辑 (稍加工)
	private String createKey(Map<String, ?> m, String className,
			String methodName) {
		StringBuffer appendStr = new StringBuffer(className + "_" + methodName);
		List<String> keys = new LinkedList<String>();
		List<String> values = new LinkedList<String>();
		for (String str : m.keySet()) {
			keys.add(str);
			if (m.get(str) != null) {
				values.add(m.get(str).toString().replace(" ", "")
						.replace(",", ""));
			} else {
				values.add("");
			}
		}
		for (int i = 0; i < values.size(); i++) {
			for (int j = i; j < values.size(); j++) {
				if (values.get(i).length() > values.get(j).length()) {
					String s = keys.get(i);
					keys.set(i, keys.get(j));
					keys.set(j, s);
					String o = values.get(i);
					values.set(i, values.get(j));
					values.set(j, o);
				}
			}
		}
		for (int i = 0; i < values.size(); i++) {
			if (values.get(i) != null && !("").equals(values.get(i))) {
				appendStr.append("_" + values.get(i).toString());
			}
		}
		return appendStr.toString();

	}
}


3. 配置AOP
在applicationContext.xml中添加
<!-- 加入Aspectj配置 -->
<aop:aspectj-autoproxy />

猜你喜欢

转载自com-niu.iteye.com/blog/2341219