springboot注解实现,spring boot自定义注解

  springboot注解实现,spring boot自定义注解

  00-1010一、Java注释1。JDK基本注释2。JDK元注释2。自定义注释1的开发。意思2。演示3。完成剖面测井作业4。完成前端响应总结。

  00-1010含义: Java注释是附加在代码上的一些元信息,在编译和运行时被一些工具用来分析和使用,具有解释和配置的功能。

  

目录

@Override ——》重写

 

  @Deprecated ——》已过时

  @SuppressWarnings(value = "unchecked") ——》压制编辑器警告

  00-1010含义:元笔记用于修改其他笔记(纪委:管干部的干部)

  、@Retention ——》定义注解的保留策略

  @ retention(retention policy . source)//注释只存在于源代码中,而默认的保留策略@ retention(retention policy . class)//不包含在类字节码文件中。注释将存在于类字节码文件中,但在运行时无法获得。@Retention(RetentionPolicy.RUNTIME)//Comments将存在于类字节码文件中,可以在运行时通过反射获得。

  、@Target ——》指定被修饰的Annotation可以放置的位置(被修饰的目标)

   @Target(ElementType.TYPE) ——》接口、类 @Target(ElementType.FIELD) ——》属性 @Target(ElementType.METHOD) ——》方法@目标(elementtype.constructor) 3354 "构造器@目标(element type . local _ variable)3354 "局部变量@Target(ElementType.PARAMETER) ——》方法参数@目标(elementtype.package) 3354 "包

   @Target(ElementType.ANNOTATION_TYPE) ——》注解,如是说:

  @ target ({elementtype.method,elementtype.type}),也就是说,这个批注可以用在方法和类上。

  注:可以指定多个位置

  、@Inherited:指定被修饰的Annotation将具有继承性

  

一、Java注解(Annotation)

 

  00-1010使用@interface关键字,其定义过程与定义接口非常相似。需要注意的是,

  批注的成员变量被声明为批注定义中没有参数的方法。它的方法名和返回值类型定义了成员变量的名称和类型,我们也可以使用default关键字来设置这个成员变量的默认值。

  

1、JDK基本注解

、@Documented:指定被修饰的该Annotation可以被javadoc工具提取成文档.

 

  、枚举类:enum,指的是常量的集合

  、注解类

  包com . LV . annotation;导入org . spring framework . beans . factory . annotation . autowi

  red;import java.lang.annotation.*;/** * @author T440s */ //生成一个注释@Documented//表示当前注解可以打在什么东西上面,此处可以放在类上与方法上@Target({ElementType.TYPE,ElementType.METHOD})//指定被修饰的Annotation将具有继承性@Inherited//注解仅存在于源码中,在class字节码文件中不包含@Retention(RetentionPolicy.SOURCE)public @interface MyAnnotation { String value() default "";}TestController.java:注意这引用了MyAnnotation注解

  

package com.lv.controller; import com.lv.annotation.MyAnnotation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller; @MyAnnotation@Controllerpublic class TestController { @Autowired private String name; @MyAnnotation public void aa(){ } }

运行后target层注解消失:注解仅存在于源码中,在class字节码文件中不包含

 

  

 

  Ⅱ、MyAnnotation注解为@Retention(RetentionPolicy.RUNTIME)时

   ——注解会在class字节码文件中存在,在运行时可以通过反射获取到

  运行test.java:

  

package com.lv.controller; import java.lang.annotation.Annotation; public class Test { public static void main(String[] args) {// 反射 for(Annotation a:TestController.class.getAnnotations()){ System.out.println(a); } }}

 

  Ⅲ、取注解里的属性值

  注解:MyAnnotation.java

  

String message() default "aaa";

拿值:

 

  

package com.lv.controller;import com.lv.annotation.MyAnnotation;import java.lang.annotation.Annotation;public class Test { public static void main(String[] args) {// 反射 for(Annotation a:TestController.class.getAnnotations()){ if(a instanceof MyAnnotation){ System.out.println(((MyAnnotation) a).message()); } } }}

 

  Ⅳ、判断在该类有无该注解

  测试:

  

package com.lv.controller;import com.lv.annotation.MyAnnotation;import java.lang.annotation.Annotation;public class Test { public static void main(String[] args) {// 直接将MyAnnotation这注解取出 MyAnnotation myAnnotation=TestController.class.getAnnotation(MyAnnotation.class); if(myAnnotation !=null){ System.out.println(myAnnotation.message()); } }}

 

  

 

  

三、完成切面日志操作

当我们在写增删改的时候,会有很多冗余的代码,后期修改很麻烦,如:

 

  

 @RequestMapping("/add") public String add(){ System.out.println("xxx在增加"); System.out.println("增加成功"); return "yes"; }

我们就可以定义aop面向切面,将前面那部分放入前置通知,后面一部分后置通知

 

  新建切面:LogAop.java

  

package com.lv.aop; import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.Signature;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.springframework.stereotype.Component; @Aspect//类不被识别,将类变成一个组件@Component@Slf4j public class LogAop {// 指定切入的规则,".."代表可有参可无参 @Pointcut("execution(* com.lv.controller.*Controller.*(..))") public void logger(){} // 环绕通知 @Around("logger()") public Object around(ProceedingJoinPoint point){ // 获得方法名称 Signature methodName=point.getSignature();// 日志输出 log.info(methodName+"进来了"); Long l1=System.currentTimeMillis();// 让方法执行 Object obj=null; try { obj=point.proceed(point.getArgs()); } catch (Throwable throwable) { throwable.printStackTrace(); } log.info(methodName+"走了"+"t耗时"+(System.currentTimeMillis()-l1)); return obj; }}

使用jrebel运行:

 

  

package com.lv.controller; import com.lv.annotation.MyAnnotation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController; @MyAnnotation//直接返回json数据@RestController//返回页面跳转数据//@Controllerpublic class TestController { @RequestMapping("/add") public String add(){ return "yes"; } @RequestMapping("/del") public String del(){ return "yes"; } @RequestMapping("/upd") public String upd(){ return "yes"; } @RequestMapping("/list") public String list(){ return "yes"; } }

 

  使用注解来开发aop日志:

  新建注解类:MyLog.java

  

package com.lv.annotation; import java.lang.annotation.*; @Inherited@Documented@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyLog { }

同样在切面类中,记得改变切入的规则

 

  

@Pointcut("@annotation(com.lv.annotation.MyLog)")

需要输出日志的方法就将新建的注解加上

 

  

 

  

 

  

四、完成前端响应反应

传入四个文件:

 

  ResponseParse.java:

  

package com.lv.response; import org.springframework.core.MethodParameter;import org.springframework.http.MediaType;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.web.bind.annotation.RestControllerAdvice;import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; /** * @author hgh *///响应增强类@RestControllerAdvicepublic class ResponseParse implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter methodParameter, Class aClass) { //返回值决定他是否需要进入beforeBodyWrite return methodParameter.getMethod().isAnnotationPresent(ResponseResult.class); } @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { //更改返回值 if (o == null) { return Result.success(); } if (o instanceof Integer) { return Result.failure(ResultCode.queryCode((Integer) o)); } if (o instanceof ResultCode) { return Result.failure((ResultCode) o); } if (o instanceof Result) { return o; } return null; }}

ResponseResult.java:

 

  

package com.lv.response; import java.lang.annotation.*; /** * @author hgh */@Retention(value = RetentionPolicy.RUNTIME)@Documented@Target({ElementType.METHOD})public @interface ResponseResult { }

Result.java:

 

  

package com.lv.response; import lombok.Data; import java.io.Serializable; /** * 响应对象封装类 * * @author hgh */@Datapublic class Result<T> implements Serializable { private final int code; private final String message; private final T data; /** * 私有构造, 只允许通过static调用构造 * * @param resultCode 结果枚举 * @param data 响应数据 */ private Result(ResultCode resultCode, T data) { this.code = resultCode.getCode(); this.message = resultCode.getMessage(); this.data = data; } /** * 成功调用返回的结果(无数据携带) * * @return Result */ public static Result success() { return success(null); } /** * 成功调用返回的结果(数据携带) * * @return Result */ public static <T> Result success(T data) { return new Result(ResultCode.SUCCESS, data); } /** * 失败调用返回的结果(数据携带) * * @param resultCode 状态枚举 * @param data 携带的数据 * @return Result */ public static <T> Result failure(ResultCode resultCode, T data) { return new Result(resultCode, data); } /** * 失败调用返回的结果(无数据携带) * * @param resultCode 状态枚举 * @return Result */ public static Result failure(ResultCode resultCode) { return failure(resultCode, null); } }

ResultCode.java:

 

  

package com.lv.response; import java.io.Serializable; /** * 响应结果码枚举 * * @author hgh */ public enum ResultCode implements Serializable { /* 正常状态 */ SUCCESS(100, "成功"), FAILURE(101, "失败"), UNKNOWN(102, "未知响应"), /** * 用户code范围: 200~300; */ USER_ACCOUNT_NOT_FIND(201, "用户名不存在"), USER_ACCOUNT_DISABLED(202, "该用户已被禁用"), USER_PASSWORD_NOT_MATCH(203, "该用户密码不一致"), USER_PERMISSION_ERROR(204, "该用户不具备访问权限"), USER_STATE_OFF_LINE(205, "该用户未登录"); private final Integer code; private final String message; ResultCode(Integer code, String message) { this.code = code; this.message = message; } public Integer getCode() { return code; } public String getMessage() { return message; } public static ResultCode queryCode(Integer code) { for (ResultCode value : values()) { if (code.equals(value.code)) { return value; } } return UNKNOWN; } }

测试:

 

  

package com.lv.controller; import com.lv.annotation.MyAnnotation;import com.lv.annotation.MyLog;import com.lv.response.ResponseResult;import com.lv.response.Result;import com.lv.response.ResultCode;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController; @MyAnnotation//直接返回json数据@RestController//返回页面跳转数据//@Controllerpublic class TestController { @MyLog @ResponseResult @RequestMapping("/add") public Result add(){ return Result.success("yes"); } @RequestMapping("/del") @ResponseResult public Object del(){ return 201; } @RequestMapping("/upd") @ResponseResult public Object upd(){ return ResultCode.USER_ACCOUNT_NOT_FIND; } @RequestMapping("/list") @ResponseResult public Object list(){ return Result.success("yes"); } }

增加:

 

  

 

  删除:

  

 

  

 

  

总结

到此这篇关于SpringBoot自定义注解的文章就介绍到这了,更多相关SpringBoot自定义注解内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

 

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: