java面试题——自定义注解常见面试题

一、注解的作用

    注解是一种元数据形式。即注解是属于java的一种数据类型,和类、接口、数组、枚举类似。
    注解用来修饰,类、方法、变量、参数、包。
    注解不会对所修饰的代码产生直接的影响。

二、创建自定义注解

基本定义

    首先使用 @interface声明注解名称
    然后,使用@Retention,@Target等元注解标注注解的生命周期和作用元素

@Retention: 表示对它所标记的元素的生命周期(参考的范围看RetentionPolicy枚举类)
@Target: 表示标记定义的注解可以和什么目标元素绑定
@Inherited: 表示该注解可以被继承
@Document: 表示该注解可以被生成API文档

三、应用场景

应用场景一:自定义注解+拦截器 实现登录校验

接下来,我们使用springboot拦截器实现这样一个功能,如果方法上加了@LoginRequired,则提示用户该接口需要登录才能访问,否则不需要登录。
首先定义一个LoginRequired注解

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface LoginRequired {

}

然后写两个简单的接口,访问sourceA,sourceB资源

@RestController

public class IndexController {


@GetMapping("/sourceA")

public String sourceA(){

return "你正在访问sourceA资源";

}

@GetMapping("/sourceB")

public String sourceB(){

return "你正在访问sourceB资源";

}

}

没添加拦截器之前成功访问



实现spring的HandlerInterceptor 类先实现拦截器,但不拦截,只是简单打印日志,如下:



    public class SourceAccessInterceptor implements HandlerInterceptor {

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    System.out.println("进入拦截器了");

    return true;

    }

    @Override

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

    }

实现spring类WebMvcConfigurer,创建配置类把拦截器添加到拦截器链中



    @Configuration

    public class InterceptorTrainConfigurer implements WebMvcConfigurer {

    @Override

    public void addInterceptors(InterceptorRegistry registry) {

    registry.addInterceptor(new SourceAccessInterceptor()).addPathPatterns("/**");

    }

    }



在sourceB方法上添加我们的登录注解@LoginRequired



    @RestController

    public class IndexController {

    @GetMapping("/sourceA")

    public String sourceA(){

    return "你正在访问sourceA资源";

    }

    @LoginRequired

    @GetMapping("/sourceB")

    public String sourceB(){

    return "你正在访问sourceB资源";

    }

    }

简单实现登录拦截逻辑



    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    System.out.println("进入拦截器了");

    // 反射获取方法上的LoginRequred注解

    HandlerMethod handlerMethod = (HandlerMethod)handler;

    LoginRequired loginRequired = handlerMethod.getMethod().getAnnotation(LoginRequired.class);

    if(loginRequired == null){

    return true;

    }

    // 有LoginRequired注解说明需要登录,提示用户登录

    response.setContentType("application/json; charset=utf-8");

    response.getWriter().print("你访问的资源需要登录");

    return false;

    }

运行成功,访问sourceB时需要登录了,访问sourceA则不用登录,

应用场景二:自定义注解+AOP   实现日志打印
 

先导入切面需要的依赖包



org.springframework.boot

spring-boot-starter-aop



定义一个注解@MyLog

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface MyLog

}

在步骤二中的IndexController写一个sourceC进行测试,加上我们的自定义注解:

@MyLog

@GetMapping("/sourceC/{source_name}")

public String sourceC(@PathVariable("source_name") String sourceName){

return "你正在访问sourceC资源";

}

你可能感兴趣的:(常见JAVA面试题,java)