欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

·AOP之注解类型

程序员文章站 2022-04-30 15:29:34
...

aop的实现,可以基于 cglib 和jdk proxy 。Java中默认使用jdk proxy。

本文是分布式项目中一个Redis缓存实例

首先我们来创建一个注解类@interface

@Target(ElementType.METHOD)	  //标识注解对方法生效
@Retention(RetentionPolicy.RUNTIME) //标识当前注解的生命周期
public @interface CacheFind {
	/**
	 *  
	 *     要求:key不同的业务一定不能重复.
	 *     
	 *     规则:
	 *     key值默认为"",
	 *               如果用户添加了key.则使用用户的
	 *               如果用户没有添加key,
	 *                   生成策略: 包名.类名.方法名::第一个参数
	 *     
	 *     添加时间: 如果不为0则需要数据添加过期时间 setex
	 */
	String key() default "";
	int seconds() default 0;
	
	
}

@Target(ElementType.METHOD)      //标识注解对方法生效
@Retention(RetentionPolicy.RUNTIME) //标识当前注解的生命周期

这两个注解针对环境变更

 

下面再创建一类标注@Aspect

//定义缓存切面
@Component //万能注解 交给容器管理
@Aspect	   //自定义切面
public class CacheAOP {
	
	@Autowired(required = false)
	private JedisCluster jedis;
	
	/**
	 * 	环绕通知的语法
	 * 	返回值类型:  任意类型用Obj包裹 
	 * 	参数说明:      必须包含并且位置是第一个  
	 * 			   ProceedingJoinPoint
	 * 	通知标识:	 
	 * 		[email protected]("切入点表达式")
	 * 		[email protected](切入点())
	 */
	@SuppressWarnings("unchecked")
	@Around("@annotation(cacheFind)")
	public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind) {
		//定义数据的返回值
		Object result = null;
		String key = getKey(joinPoint,cacheFind);
		String value = jedis.get(key);
		if(StringUtils.isEmpty(value)) {
			try {
				//缓存数据为null.查询数据库
				result = joinPoint.proceed();
				String json = ObjectMapperUtil.toJSON(result);
				
				if(cacheFind.seconds() >0) {
					//需要添加超时时间
					jedis.setex(key,cacheFind.seconds(), json);
				}else {
					jedis.set(key, json);
				}
				System.out.println("AOP实现数据库查询!!!!!");
			} catch (Throwable e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
			
		}else {
			//缓存数据不为null 需要将json转化为对象
			Class returnType = getReturnType(joinPoint);
			result = ObjectMapperUtil.toObject(value, returnType);
			System.out.println("AOP实现缓存查询!!!!!");
		}
		
		return result;
	}
}

JSON转换的工具类(需要jackson)

public class ObjectMapperUtil {

	private static final ObjectMapper MAPPER = new ObjectMapper();

	//1.将对象转化为json
	//如果程序有异常,转化为运行时异常
	public static String toJSON(Object obj) {

		String json = null;
		try {
			json = MAPPER.writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}

		return json;
	}
	
	
	/**
	 * 要求:用户传递什么类型,返回什么对象.
	 * 方案: 使用泛型对象实现!!!
	 * @param json
	 * @param targetClass
	 * @return
	 */
	public static <T> T toObject(String json,Class<T> targetClass) {

		T t = null;
		try {
			t = MAPPER.readValue(json, targetClass);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}

		return t;
	}
}

这样@CacheFind标注的方法就会进行缓存判断了!

相关标签: 知识总结