java spring自定义注解

自定义注解其实非常简单,共3步,重点是2和3步

1、定义注解类,用于标识目标位置

2、拦截目标,为拿到目标字节码对象,这里重点是怎么拦截,根据场景不同使用不同拦截技术

参考:Java三大器:过滤器、监听器、拦截器_墨殇离陌的博客-优快云博客

  • 使用AOP(只能拦截方法)
  • 使用Filter(只能在有Servlet 中使用,只能是web应用使用) 
  • 使用拦截器 
  • 使用动态代理 

3、拿到字节码对象,利用反射技术对对象内部结构进行改造。

举个栗子,这个例子功能没有啥实际作用,用来参考:

注解在方法形参上,可将String时间戳转换成-->指定String日期格式,如格式转换失败则不做操作

 

 定义注解类

@Target({ElementType.PARAMETER})  //作用在方法参数上
@Retention(RetentionPolicy.RUNTIME)
public @interface TransitionDate {
    String value() default "yyyy-MM-dd HH:mm:ss";
}

使用aop拦截和反射处理

@Component
@Aspect
public class TransitionDateAspect {

    /**
     * 注解在方法形参上,可将String时间戳转换成-->指定String日期格式,如格式转换失败则不做操作
     */
    @Before("execution(public * icu.weizhan.service.*.*(..)))")
    public void transitionDateOfParam(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        if (args.length == 0){
            return;  //没有参数不用解析
        }
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();  //这里获得方法对象才能使用getParameterAnnotations获取参数注解
        //一个方法中有多个参数,一个参数中有多个注解,所以要用二维数组
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        //遍历多个参数
        for (int i = 0; i < parameterAnnotations.length; i++) {
            Object arg = args[i];  //形参
            //遍历多个注解
            for (Annotation annotation : parameterAnnotations[i]) {
                if (annotation.annotationType().equals(TransitionDate.class)){
                    TransitionDate transitionDate = (TransitionDate) annotation;
                    String value = transitionDate.value();  //获取注解的value值
                    if (arg.getClass().equals(String.class)){
                        //转换
                        try {
                            Long aLong = Long.valueOf((String) arg);
                            Date date = new Date(aLong);
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(value);
                            String format = simpleDateFormat.format(date);
                            //重新给形参赋值
                            Field field = arg.getClass().getDeclaredField("value");
                            field.setAccessible(true);
                            field.set(arg,format.toCharArray());
                        }catch (Exception e){
                        }
                    }
                }
            }
        }

    }
}

 测试

    public String test(@TransitionDate String date){
        System.out.println(date);
        return date;
    }
    
    @Test
    public void transitionDateTest(){
        transitionDateTest.test("1687452113476");
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值