拿到注解值

5 篇文章 0 订阅

切面注解

@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface GmallCache {
//    String bloomPrefix() default "";
//    String bloomSuffix() default "";
    //cacheKeyExpr #{} 不能乱写,参考GmallCacheAspect规定好的
    String cacheKeyExpr() default  "";
    boolean enableBloom() default true;
    String bloomName() default "";
    long ttl() default -1L;
    long missTtl() default -1L;
}
@GmallCache(
            cacheKeyExpr = RedisConst.SKUKEY_PREFIX+"#{#args[0]}"+RedisConst.SKUKEY_SUFFIX,
            enableBloom = true,
            ttl = 60 * 1000 * 30, bloomName = BloomName.SKU, missTtl = 60 * 1000 * 10)
    @Override
    public Map<String, Object> getSkuInfo(Long skuId) {}
@Slf4j
@Component
@Aspect
public class GmallCacheAspect {
    @Qualifier(BloomName.SKU)
    @Autowired
    RBloomFilter<Object> skuBloomFilter;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * key: bloomname(组件)  value:组件的对象
     */
    @Autowired
    Map<String, RBloomFilter<Object>> blooms;


    @Around("@annotation(com.atguigu.gmall.common.cache.GmallCache)")
    public Object cacheAround(ProceedingJoinPoint pjp) throws Throwable {
        //ReentrantLock lock = new ReentrantLock();
        //拿到目标方法的参数
        Object[] args = pjp.getArgs();
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        GmallCache gmallCache = signature.getMethod().getAnnotation(GmallCache.class);
//        String prefix = gmallCache.bloomPrefix();
//        String suffix = gmallCache.bloomSuffix();
        //解析表达式,动态传入
        String cacheKeyExpr = gmallCache.cacheKeyExpr();
        String key = parseExpression(cacheKeyExpr, pjp);

        //是否开启布隆
        boolean enableBloom = gmallCache.enableBloom();
        String bloomName = gmallCache.bloomName();
        long ttl = gmallCache.ttl();
        long missTtl = gmallCache.missTtl();
//        String  key = prefix +args[0]+suffix;
        String intern = key.intern();
        //前置通知
        Object cache = queryFromCache(key, method);

        if (cache != null) {
            log.info("缓存命中");
            return cache;
        }
        try {
            //开始查询缓存
            if (enableBloom) {
                RBloomFilter<Object> bloomFilter = blooms.get(bloomName);
                boolean contains = bloomFilter.contains(key);
                if (!contains) {
                    log.info("布隆无此值");
                    return null;
                }
            }
            if (cache == null) {
                synchronized (intern) {
                    Object cacheAgain = queryFromCache(key, method);
                    if (cacheAgain == null) {
                        //目标方法
                        log.info("查询数据库");
                        Object proceed = pjp.proceed(args);
                        //保存到缓存
                        saveToCache(key, proceed, ttl, missTtl);
                        //返回通知
                        return proceed;
                    }
                    log.info("双检查缓存命中");
                    return cacheAgain;
                }
            }
        } catch (Exception e) {
            //异常通知
            throw new RuntimeException(e);
        } finally {
            //后置通知,分布式锁在这解锁
        }
        return cache;
    }

    private String parseExpression(String cacheKeyExpr, ProceedingJoinPoint pjp) {
        //准备解析器
        SpelExpressionParser expressionParser = new SpelExpressionParser();
        //得到表达式对象
        Expression expression = expressionParser.parseExpression(cacheKeyExpr, new TemplateParserContext());
        //获得表达式的值
        EvaluationContext context = new StandardEvaluationContext();
        Object[] argsList = pjp.getArgs();
        context.setVariable("args", argsList);

        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        context.setVariable("method",method);
        //都是返回缓存的key
        String value = expression.getValue(context, String.class);
        return value;
    }

    //保存到缓存
    private void saveToCache(String key, Object proceed, long ttl, long missTtl) throws JsonProcessingException {
       
    }

    //查询缓存
    public Object queryFromCache(String key, Method method) throws JsonProcessingException {
       
}

字段注解

1.实体类
public class SysUser 
{
    // @JsonProperty("roleIdList")
    private Long[] roleIds;
}
 
public Long[] getRoleIds()
{
    return roleIds;
}
 
public void setRoleIds(Long[] roleIds)
{
    this.roleIds = roleIds;
}

2.反射
import com.fasterxml.jackson.annotation.JsonProperty;
 
public static Object getFieldValueByObject(Object object, String targetFieldName) throws Exception {
		// 获取该对象的Class
		Class objClass = object.getClass();
		// 初始化返回值
		Object result = null;
		// 获取所有的属性数组
		Field[] fields = objClass.getDeclaredFields();
		for (Field field : fields) {
			// 属性名称
			String currentFieldName = "";
			// 获取属性上面的注解 import com.fasterxml.jackson.annotation.JsonProperty;
			/**
			 * 举例: @JsonProperty("roleIds") 
             * private String roleIds;
			 */
			try {
				boolean has_JsonProperty = field.isAnnotationPresent(JsonProperty.class);
				if (has_JsonProperty) {
					currentFieldName = field.getAnnotation(JsonProperty.class).value();
				} else {
					currentFieldName = field.getName();
				}
				
				if (currentFieldName.equals(targetFieldName)) {
					field.setAccessible(true);
					result = field.get(object);
					return result; // 通过反射拿到该属性在此对象中的值(也可能是个对象)
				}
				
			} catch (SecurityException e) {
				// 安全性异常
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// 非法参数
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// 无访问权限
				e.printStackTrace();
			}			
		}
		return result;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值