Java语言06之注解

1 注解是什么

注解本质是一个继承Annotation的特殊接口,只有被解析之后才会生效,常见的解析方法有两种:

  • 编译期直接扫描:编译器在编译的时候扫描对应的注解并处理,比如某个方法使用@Override注解,在编译的时候就会检测当前的方法是否重写了父类对应的方法。
  • 运行期通过反射处理:比如Spring框架的@Value、@Component都是通过反射来进行处理的。

2 自定义注解

只要理解和记住jdk内置的四个注解即可 (@Target,@Retention,@Documented,@Inherited)

  • @Retention:保留的时间范围 (RetentionPolicy)
    • SOURCE源文件保留(如@Override保留在源文件,编译后注解消失)
    • CLASS编译时保留(如lombok生成get/set)
    • RUNTIME运行时保留(如切面记录日志,或验证参数信息等)
  • @Target:使用范围
    • ElementType.FIELD
    • ElementType.METHOD
    • ElementType.PARAMETER
    • ElementType.LOCAL_VARIABLE
    • ElementType.TYPE_USE
  • @Documented:保留注解信息
  • @Inherited:子类注解自动继承该注解

3 注解实战

3.1 结合Spring拦截器实现用户权限校验

通过Spring拦截器拦截被自定义注解的方法,来实现功能:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginRequired {
	// 不需要定义任何方法
}

定义了一个登陆注解。通过拦截器拦截请求时,判断是否添加了该注解,如果这个请求添加了该注解,那么就会去ThreadLocal中判断有没有保存当前用户的信息,没有的话就不放行请求,让用户去登陆先。

@Component
public class LoginRequiredInterceptor implements HandlerInterceptor {

    @Autowired
    private HostHolder hostHolder;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
            if (loginRequired != null && hostHolder.getUser() == null) {
                response.sendRedirect(request.getContextPath() + "/login");
                return false;
            }
        }
        return true;
    }
}

3.2 结合Spring AOP实现

定义一个注解

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Log {
}

定义切面:

@Component
@Aspect
@Slf4j
public class LogAspect {
   @Pointcut(value = "@annotation(com.lrm.boot.hello.Log)")
   public void log() {
   }

   @Around("log()")
   public Object doAround(ProceedingJoinPoint joinPoint) {
       Object obj = null;
       try {
           long beginTime = System.currentTimeMillis();
           obj = joinPoint.proceed();
           // 获取方法信息
           String methodName = joinPoint.getSignature().getName();
           String className = joinPoint.getSignature().getDeclaringTypeName();
           log.info("类:[{}],方法:[{}]耗时时间为:[{}]", className, methodName, System.currentTimeMillis() - beginTime + "毫秒");
       } catch (Throwable throwable) {
           throwable.printStackTrace();
       }
       return obj;
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值