Spring AOP实例

xiaoxiao2021-02-28  99

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

转载请注明原文地址: https://www.6miu.com/read-82603.html

最新回复(0)