java自定义注解语法_自定义注解实战

自定义注解实战

Java注解又称Java标注,是Java语言5.0版本开始支持加入源代码的特殊语法元数据

Java注解为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。

Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取注解内容。在编译器生成类文件时,注解可以被嵌入到字节码中。Java虚拟机可以保留注解内容,在运行时可以获取到注解内容。

Java注解概述

jdk1.5版本内置了三种标准的注解:

@Override,表示当前的方法定义将覆盖超类中的方法。

@Deprecated,表示注解的代码是不赞成使用的代码(即将被弃用的代码)

@SuppressWarnings,告诉编译器忽略指定的警告,不用在编译完成后出现警告信息

同时Java还提供了4种注解用于新注解的创建:

@Target:用于说明注解修饰的范围。

可以在以下范围内选择一个。

ElementType.METHOD:方法声明

ElementType.TYPE:类、接口(包括注解类型)或enum声明

ElementType.CONSTRUCTOR:构造器的声明

ElementType.FIELD:域声明(包括enum实例)

ElementType.LOCAL_VARIABLE:局部变量声明

ElementType.PACKAGE:包声明

ElementType.PARAMETER:参数声明

@Retention:表示需要在什么级别保存该注解信息

RetentionPolicy.RUNTIME:运行期间保留注解,可以通过反射机制读取注解信息

RetentionPolicy.SOURCE:注解将被编译器丢弃

RetentionPolicy.CLASS:注解在class文件中可用,但会被VM丢弃

@Document:表示将注解包含在Javadoc中

@Inherited:允许子类继承父类中的注解,默认不能被子类继承

如何自定义注解

自定义注解很简单,只需要将上面元注解使用好即可。

以我们这次项目中的自定义注解为例:

@Target(ElementType.PARAMETER)

@Retention(RetentionPolicy.RUNTIME)

public @interface CurrentUser {

}

分析一下这个注解。

@Target(ElementType.PARAMETER) 表示该注解是使用范围是参数

@Retention(RetentionPolicy.RUNTIME) 表示运行期间保留注解,并且可以通过反射机制读取注解信息

这两个注解加在一起表示,@CurrentUser 这个注解是用来标注参数的,它在运行时还能获取到注解信息。

自定义注解实战

如果只是单纯地写一个注解,这个注解就没有任何实际价值。我们需要通过处理这个注解来达到我们想要的结果,

项目需求是希望通过@CurrentUser注解获取当前登录用户的userId。

我们会怎么做呢?下面是我们处理的逻辑图:

71e10526d97a0c99b1ff6c594800535d.png

按照步骤拆分自定义注解的使用:

第一步,自定义注解。

第二步,继承HandlerMethodArgumentResolver,实现数据绑定。

spring调用HandlerMethodArgumentResolver实现Controller的参数装配。HandlerMethodArgumentResolver实现类中会调用DataBinder,Converter等。常用的该接口实现类有:

ServletModelAttributeMethodProcessor: 实体类的组装用它实现。

RequestParamMethodArgumentResolver: 基本数据类型如String用它实现。

RequestParamMethodArgumentResolver接口定义了实现类必须实现supportsParameter和resolveArgument这两个方法。

第一个方法表示这个方法的参数是否支持这个解析器,第二个方法将方法参数解析为来自给定请求的参数值。

自定义解析器都需要实现这个接口,下面是我们在项目中的实现类:

public class UserModelResolver implements HandlerMethodArgumentResolver {

public static final String REQUEST_USERID = "x-erp-auth-id";

@Override

public boolean supportsParameter(MethodParameter parameter) {

//如果有CurrentUser注解则支持

return parameter.hasParameterAnnotation(CurrentUser.class);

}

@Override

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,

NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

Integer userId = 0;

//取出鉴权网关存入的登录用户Id,内部服务调显示赋值userId

String headerData = webRequest.getHeader(REQUEST_USERID);

if (!Strings.isNullOrEmpty(headerData)) {

try {

userId = Integer.parseInt((String) headerData);

} catch (NumberFormatException nfe) {

userId = 0;

}

}

return userId;

}

}

第三步,在方法中使用,代码如下

@GetMapping("/listDevices")

public BaseReturnVO listShopDevice(@CurrentUser Integer userId, @Valid @NotNull(message = "shopPublicId为空") Integer shopPublicId){

...

}

是不是很简单实用?

The End

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[自定义注解实战]http://www.zyiz.net/tech/detail-91271.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值