自定义注解实现 查询redis缓存

一、注解的基础

1.注解的定义:Java文件叫做Annotation,用@interface表示。

2.元注解:@interface上面按需要注解上一些东西,包括@Retention、@Target、@Document、@Inherited四种。

3.注解的保留策略:

  @Retention(RetentionPolicy.SOURCE)   // 注解仅存在于源码中,在class字节码文件中不包含

  @Retention(RetentionPolicy.CLASS)     // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得

  @Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

4.注解的作用目标:

  @Target(ElementType.TYPE)                      // 接口、类、枚举、注解

  @Target(ElementType.FIELD)                     // 字段、枚举的常量

  @Target(ElementType.METHOD)                 // 方法

  @Target(ElementType.PARAMETER)            // 方法参数

  @Target(ElementType.CONSTRUCTOR)       // 构造函数

  @Target(ElementType.LOCAL_VARIABLE)   // 局部变量

  @Target(ElementType.ANNOTATION_TYPE) // 注解

  @Target(ElementType.PACKAGE)               // 包

5.注解包含在javadoc中:

  @Documented

6.注解可以被继承:

  @Inherited

7.注解解析器:用来解析自定义注解。

2、实现缓存系统

介绍:

在service的查询方法里面,在先查询之前 查询下redis,没有数据的话再调用service的方法进行业务的查询

结构图

2.1 注解类:

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheAnno {

	/**
	 * 缓存ID
	 */
	String key() default "";

}

2.2、参数解析类:

import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.StringUtils;

public class AnnoParse {

	/**
	 * 解析传入的key值
	 * 
	 * @param field
	 * @param method
	 * @param args
	 * @return
	 */
	public static final String parseKey(String field, Method method, Object[] args) {
		if (!StringUtils.hasLength(field))
			return null;

		LocalVariableTableParameterNameDiscoverer nd = new LocalVariableTableParameterNameDiscoverer();
		String[] parameterNames = nd.getParameterNames(method);
		ExpressionParser parser = new SpelExpressionParser();
		StandardEvaluationContext context = new StandardEvaluationContext();

		for (int i = 0; i < parameterNames.length; i++) {
			context.setVariable(parameterNames[i], args[i]);
		}

		return parser.parseExpression(field).getValue(context, String.class);
	}
}

2.3、自定义redis缓存系统:

/**
 * 模拟 redis 缓存系统
 */
public class RedisCache {

	public static final Map redis = new ConcurrentHashMap();

	public static Object get(String key) {
		return redis.get(key);
	}

	public static void set(String key, Object obj) {
		redis.put(key, obj);
	}

}

2.4、重点:缓存切面类(实现类)

@Aspect
@Component
public class CacheAnnoAspect {

	@SuppressWarnings("rawtypes")
	@Around("@annotation(ca)")
	public Object cache(ProceedingJoinPoint pjp, CacheAnno ca) throws Throwable {

		// 获取参数的类型
		Class[] argTypes = ((MethodSignature) pjp.getSignature()).getParameterTypes();

		Method method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argTypes);

		CacheAnno cacheAnno = method.getAnnotation(CacheAnno.class);

		String keyValue = AnnoParse.parseKey(cacheAnno.key(), method, pjp.getArgs());

		// Class modelType = method.getAnnotation(CacheAnno.class).annotationType();

		// String keyName = modelType.getName();

		Object obj = RedisCache.get(keyValue);
		if (obj != null) {
			System.out.println("从缓存中获取数据");
			return obj;
		}

		obj = pjp.proceed();

		if (obj != null) {
			RedisCache.set(keyValue, obj);
		}

		System.out.println("从数据库中获取数据");
		return obj;
	}

}

2.5、service类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.th.anno.CacheAnno;
import com.th.dao.OrderDao;
import com.th.entity.OrderEntity;
import com.th.service.OrderService;

@Service
public class OrderServiceImpl implements OrderService {

	@Autowired
	private OrderDao orderDao;

	@Override
	@CacheAnno(key = "#id")
	public OrderEntity findOrderById(Integer id) {
		OrderEntity orderEntity = orderDao.select(id);
		return orderEntity;
	}

}

2.6、测试

package com.th.test;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.th.entity.OrderEntity;
import com.th.service.OrderService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:applicationContext.xml" })
public class Test {

	@Autowired
	private OrderService orderService;

	@org.junit.Test
	public void test() {
		OrderEntity order = orderService.findOrderById(1);
		order = orderService.findOrderById(1);
		System.out.println(order);
		
		//数据库没有2的 所以查询后 也不能缓存数据 每次查询依然查询数据库
		order = orderService.findOrderById(2);
		order = orderService.findOrderById(2);
		order = orderService.findOrderById(2);
	}

}

2.7、测试结果:

你可能感兴趣的:(常用技术,系统架构)