java注解详情及自定义注解和使用场景

  • 注解概念
  • jdk预定义的注解
  • jdk提供了4个元注解
  • JDK中给我们提供的4个元注解
  • 1.@Target:描述当前注解能够作用的位置
  • 2.@Retention: 描述注解被保留到的阶段
  • 3.@Documented:描述注解是否被抽取到JavaDoc api中
  • 4.@inherited:描述注解是否可以被子类继承
  • 自定义注解
  • 注解的样式
  • 注解的本质
  • 自定义注解
  • 自定义注解
  • 定义studnet1类
  • 测试
  • 注解应用场景
  • 场景一:自定义注解+拦截器 实现登录校验
  • 场景二:自定义注解+AOP 实现接口执行时间打印


注解概念

注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

jdk预定义的注解

@Override:检查被该注解标注的方式是否是继承自父类【接口】
@Deprecated: 该注解表示注释的内容过时
@SuppressWarnings: 压制警告

jdk提供了4个元注解

JDK中给我们提供的4个元注解

1.@Target:描述当前注解能够作用的位置

ElementType.TYPE:可以作用在类上
ElementType.METHOD:可以作用在方法上
ElementType.FIELD:可以作用在成员变量上

2.@Retention: 描述注解被保留到的阶段

SOURCE < CLASS < RUNTIME
SOURCE:表示当前注解只在代码阶段有效
CLASS:表示该注解会被保留到字节码阶段
RUNTIME:表示该注解会被保留到运行阶段 JVM
自定义的注解:RetentionPolicy.RUNTIME

3.@Documented:描述注解是否被抽取到JavaDoc api中
4.@inherited:描述注解是否可以被子类继承

自定义注解

注解的样式

// 元注解
public @interface 注解名称{
// 属性列表
}

注解的本质

在对该注解类的class文件进行反编译时,发现注解的本质是接口,并继承java.lang.annotation.Annotation

android 自定义注解与注解处理器demo 自定义注解的使用场景_ide

自定义注解

了解本质后,我们来进行自定义注解的讲解
自定义注解
@Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface InvokAnno {
 String className();
 String methodName();
 }定义studnet1类
public class Student1 {
 public void show(){
 System.out.println(“student1 show …”);
 }
 }测试
@InvokAnno(className = “com.gupao.edu.anno2.Student2”,methodName = “show”)
 public class MyMain {
 public static void main(String[] args) throws Exception {
 // 获取类对象
 Class clazz = MyMain.class;
 // 获取类对象中的注解
 InvokAnno an = clazz.getAnnotation(InvokAnno.class);
 /**• 注解本质是 接口 获取到的其实是接口的实现
• public class MyInvokAnno implements InvokAnno{

• 
• String className(){

• return “com.gupao.edu.anno2.Student1”;
• }
• String methodName(){

• return “show”;
• }
• }
 */
 // 获取注解中对应的属性
 String className = an.className();
 String methodName = an.methodName();
 System.out.println(className);
 System.out.println(methodName);// 通过反射的方式实现接口的功能
 Class<?> aClass = Class.forName(className);
 Method show = aClass.getDeclaredMethod(“show”);
 // 方法的执行
 Object o = aClass.newInstance();
 show.invoke(o); // 执行对应的方法
 }
 }

注解应用场景

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

1.手写注解
 @Target(ElementType.METHOD)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface LoginAnnotaion {
 }2.拦截器
 @Configuration
 public class WebMvcConfigurerTest implements WebMvcConfigurer {
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
 registry.addInterceptor(new TestInterceptor()).addPathPatterns("/").excludePathPatterns("/js/","/css/","/images/");
 }
 }public class TestInterceptor implements HandlerInterceptor {
 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 System.out.println(“拦截了”);
 HandlerMethod handlerMethod=(HandlerMethod)handler;
 //获取拦截的方法
 LoginAnnotaion loginAnnotaion=handlerMethod.getMethod().getAnnotation(LoginAnnotaion.class);
 //该方法有这个注解,放行,不拦截
 if(loginAnnotaion!=null){
 return true;
 }
 response.setContentType(“application/json; charset=utf-8”);
 response.getWriter().print(“你访问的资源需要先登录”);
 return false;
 }@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 {}
 }3.controller
 @RestController
 public class TestController {//放开
 @LoginAnnotaion
 @GetMapping("/way/{id}")
 public String way(@PathVariable(“id”) Integer id){
 return id.toString()+“way”;
 }@GetMapping("/way2/{id}")
 public String way2(@PathVariable(“id”) Integer id){
 return id.toString()+“way2”;
 }
 }

场景二:自定义注解+AOP 实现接口执行时间打印

先导入切面和lombok需要的依赖包

 org.springframework.boot
 spring-boot-starter-aop


 org.projectlombok
 lombok
 true定义一个注解
 @Target({ElementType.TYPE,ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
 public @interface AopAnnotation {
 }写一个aop
 @Aspect
 @Component
 @Slf4j
 public class LogAspect {@Pointcut(value = “@within(com.example.loginrequireannotation.annotation.AopAnnotation) || @annotation(com.example.loginrequireannotation.annotation.AopAnnotation)”)
 public void logPointCut(){
 }// 3. 环绕通知
3.controller
 @AopAnnotation
 @RestController
 public class AopController {@LoginAnnotaion
 @GetMapping("/user/{id}")
 public String way(@PathVariable(“id”) Integer id){
 return id.toString()+“user”;
 }
@Around(value = "logPointCut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("====== 开始执行 {}.{} ======",
joinPoint.getTarget().getClass(),
joinPoint.getSignature().getName());
// 记录开始时间
long begin = System.currentTimeMillis();

// 执行目标 service
Object result = joinPoint.proceed();

// 记录结束时间
long end = System.currentTimeMillis();
long takeTime = end - begin;
if (takeTime > 3000) {
log.error("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
} else if (takeTime > 2000) {
log.warn("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
} else {
log.info("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
}
return result;
}
}

@LoginAnnotaion
@GetMapping("/teacher/{id}")
public String way2(@PathVariable(“id”) Integer id){
return id.toString()+“teacher”;
}
}

android 自定义注解与注解处理器demo 自定义注解的使用场景_System_02