前面讲了理论部分,现在开始具体运用。  需求:通过在方法加@MyAnnotation自动实现,从缓存取,若没有就从别的地方取值,然后再入缓存。
 
 
自定义注解MyAnnotation  
/**
 * Created by King on 2017/8/30.
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @
interface MyAnnotation {
    String key();
    String hashKey();
    ValueType valueType();
} 
ValueType:是一个枚举类,定义了redis缓存的数据类型
 
 
目标方法 
@MyAnnotation(key
="aaaaaaaaaaabbb",valueType 
= ValueType
.Hash,hashKey 
= "11111111")
    
public List<String> searchType11(
Integer a) {
        
List<String> list = Lists
.newArrayList();
        
        
list.add(
"执行Controller方法,为了测试22222222222");
        
return list;
    } 
 
切面Aspect 
@Aspect
@Component
public class ShiliAspect {
    private static final Logger logger = LoggerFactory.getLogger(ShiliAspect.class);
    
@Autowired
    RedisTemplate redisTemplate;
    
@Pointcut(
"@annotation(com.cci.market.security.aop.MyAnnotation)")
    
public void save(){
    }
    
@Around(
"save()")
    
public Object 
addOperateLog(ProceedingJoinPoint pjp) 
throws Throwable {
        
        String methodName = pjp.getSignature().getName();
        
        Method method = getMethod(pjp);
        
        MyAnnotation cacheable = method.getAnnotation(MyAnnotation.class);
        Object returnObj = 
null;
        
if (cacheable.valueType().equals(ValueType.Map)){
            
            Map<String, Object> map  = redisTemplate.opsForHash().entries(cacheable.key());
            
if (map != 
null && map.size()>
0) {
                map.put(
"AOP",
"这是从缓存去的");
                map.put(
"cacheable.name()",cacheable.key());
                
return map;
            }
        } 
else if (cacheable.valueType().equals(ValueType.Hash)){
            returnObj = redisTemplate.opsForHash().get(cacheable.key(),cacheable.hashKey());
            
if (returnObj != 
null) {
                
return returnObj;
            }
        }
        
try{
            
            returnObj = pjp.proceed(pjp.getArgs());
            
            
if (cacheable.valueType().equals(ValueType.Map)){
                redisTemplate.opsForHash().putAll(cacheable.key(), (Map) returnObj);
            } 
else if (cacheable.valueType().equals(ValueType.Hash)){
                redisTemplate.opsForHash().put(cacheable.key(),cacheable.hashKey(),returnObj);
            }
            
            redisTemplate.expire(cacheable.key(), 
10, TimeUnit.SECONDS);
        }
catch (Exception e){
            logger.error(e.getMessage(),e);
        }
        
return returnObj;
    }
    
public static Method 
getMethod(ProceedingJoinPoint pjp) {
        
        Object[] args = pjp.getArgs();
        
        Class[] argTypes = 
new Class[pjp.getArgs().length];
        
for (
int i = 
0; i < args.length; i++) {
            
if (args[i] != 
null) {
                argTypes[i] = args[i].getClass();
            }
        }
        Method method = 
null;
        
try {
            
            method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argTypes);
        } 
catch (NoSuchMethodException e) {
            e.printStackTrace();
        } 
catch (SecurityException e) {
            e.printStackTrace();
        }
        
return method;
    }
}
 
改进:如果目标方法参数类型是int,long等,通过上述方法获取参数类型,直接变成了相应封装类。再根据方法名和参数类型去获取目标方法,会找不到。  其实获取目标方法有更加简单方法:  **//获取目标方法  Method method = ((MethodSignature) pjp.getSignature()).getMethod();**