Spring AOP实例

前面讲了理论部分,现在开始具体运用。
需求:通过在方法加@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();
        //type为null,则查询所有
        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();**

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值