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.注解解析器:用来解析自定义注解。
介绍:
在service的查询方法里面,在先查询之前 查询下redis,没有数据的话再调用service的方法进行业务的查询
结构图
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 "";
}
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);
}
}
/**
* 模拟 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);
}
}
@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;
}
}
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;
}
}
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);
}
}