在上一篇文章《SpringBoot进阶教程(六十四)注解大全》中介绍了springboot的常用注解,springboot提供的注解非常的多,这些注解简化了我们的很多操作。今天主要介绍介绍自定义注解。

自spring4.0开放以来,自定义注解非常常见,项目中都会或多或少的使用自定义注解,我们的demo中主要针对登录校验来介绍如何量身定制自定义注解。

v项目结构

v定义注解

package learn.web.controller.interceptor;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; /**
* @author toutou
* @date by 2020/11
* @des
*/
@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface Login {
}

元注解释义:

java.lang.annotation提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):

@Documented:注解是否将包含在JavaDoc中

@Retention:什么时候使用该注解,指明修饰的注解的生存周期,即会保留到哪个阶段。

1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略
2.RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
3.RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用

@Target:注解用于什么地方,指明了修饰的这个注解的使用范围,即被描述的注解可以用在哪里。

1.TYPE——用于描述类、接口(包括注解类型) 或enum声明
2.FIELD——用于字段声明(包括枚举常量)
3.METHOD——用于方法声明
4.PARAMETER——用于参数声明
5.CONSTRUCTOR——用于构造函数声明
6.LOCAL_VARIABLE——用于本地变量声明
7.ANNOTATION_TYPE——用于注解类型声明
8.PACKAGE——用于包声明
9.TYPE_PARAMETER—— 用于类型参数声明,JavaSE8引进,可以应用于类的泛型声明之处
10.TYPE_USE——JavaSE8引进,此类型包括类型声明和类型参数声明,是为了方便设计者进行类型检查,例如,如果使用@Target(ElementType.TYPE_USE)对@NonNull进行标记,则类型检查器可以将@NonNull class C {...} C类的所有变量都视为非null

@Inherited:是否允许子类继承该注解

v实现注解

/**
* @author toutou
* @date by 2020/11
* @des
*/
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor");
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
Login login = method.getAnnotation(Login.class);
if(login!=null) {
// login!=null表示@Login注解生效
if(!"user".equals(request.getParameter("user"))){
new RuntimeException("没有登录.");
}
}
} return true;
}
}

v配置拦截器

package learn.web.controller.config;

import learn.web.controller.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; /**
* @author toutou
* @date by 2020/11
* @des
*/
@Configuration
public class WebMvcConfig extends DelegatingWebMvcConfiguration {
@Autowired
LoginInterceptor loginInterceptor; @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor);
super.addInterceptors(registry);
System.out.println("Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor Interceptor");
}
}

v使用注解

@RestController
public class UserController {
@GetMapping("/user/hello")
@Login
public String helloWorld() {
return "hello world.";
}
}

v源码地址

https://github.com/toutouge/javademosecond/tree/master/hellolearn

v博客总结

写到这才发现,项目结构目录有点小问题,interceptor和config两个包应该是和controller平行的,而不是controller的子目录。即:package learn.web.controller.interceptor改成package learn.web.interceptor;learn.web.controller.config改成learn.web.config。原文就懒得重新捯饬了,大家注意下就行,当然原文也不会有问题,只是目录结构改一下会更好。

作  者:请叫我头头哥


出  处:http://www.cnblogs.com/toutou/


关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!


版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。


特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信


声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

#comment_body_3242240 { display: none }

SpringBoot进阶教程(六十五)自定义注解的更多相关文章

  1. SpringBoot进阶教程(六十四)注解大全

    在Spring1.x时代,还没出现注解,需要大量xml配置文件并在内部编写大量bean标签.Java5推出新特性annotation,为spring的更新奠定了基础.从Spring 2.X开始spri ...

  2. SpringBoot进阶教程(六十八)Sentinel实现限流降级

    前面两篇文章nginx限流配置和SpringBoot进阶教程(六十七)RateLimiter限流,我们介绍了如何使用nginx和RateLimiter限流,这篇文章介绍另外一种限流方式---Senti ...

  3. SpringBoot进阶教程(六十)intellij idea project下建多个module搭建架构(上)

    在 IntelliJ IDEA 中,没有类似于 Eclipse 工作空间(Workspace)的概念,而是提出了Project和Module这两个概念.多module有一个父maven工程,多个子工程 ...

  4. SpringBoot进阶教程(二十五)整合Redis之@Cacheable、@CachePut、@CacheEvict的应用

    在上一篇文章(<SpringBoot(二十四)整合Redis>)中,已经实现了Spring Boot对Redis的整合,既然已经讲到Cache了,今天就介绍介绍缓存注解.各家互联网产品现在 ...

  5. SpringBoot进阶教程(六十二)整合Kafka

    在上一篇文章<Linux安装Kafka>中,已经介绍了如何在Linux安装Kafka,以及Kafka的启动/关闭和创建发话题并产生消息和消费消息.这篇文章就介绍介绍SpringBoot整合 ...

  6. SpringBoot进阶教程(六十九)ApplicationContextAware

    在某些特殊的情况下,Bean需要实现某个功能,但该功能必须借助于Spring容器才能实现,此时就必须让该Bean先获取Spring容器,然后借助于Spring容器实现该功能.为了让Bean获取它所在的 ...

  7. SpringBoot进阶教程(六十一)intellij idea project下建多个module搭建架构(下)

    在上一篇文章<SpringBoot进阶教程(六十)intellij idea project下建多个module(上)>中,我们已经介绍了在intellij idea中创建project之 ...

  8. SpringBoot进阶教程(二十九)整合Redis 发布订阅

    SUBSCRIBE, UNSUBSCRIBE 和 PUBLISH 实现了 发布/订阅消息范例,发送者 (publishers) 不用编程就可以向特定的接受者发送消息 (subscribers). Ra ...

  9. SpringBoot进阶教程(七十四)整合ELK

    在上一篇文章<SpringBoot进阶教程(七十三)整合elasticsearch >,已经详细介绍了关于elasticsearch的安装与使用,现在主要来看看关于ELK的定义.安装及使用 ...

随机推荐

  1. 使用appium后安卓手机无法调出键盘解决方法

    问题:用appium进行真机调试后,使用手机的app进行输入时无法调出键盘. 原因:appium调试时,将手机输入法设置成了Unicode IME 解决方法: 方法一,手机设置里修改输入法: 不同的手 ...

  2. 详解工程师不可不会的LRU缓存淘汰算法

    大家好,欢迎大家来到算法数据结构专题,今天我们和大家聊一个非常常用的算法,叫做LRU. LRU的英文全称是Least Recently Used,也即最不经常使用.我们看着好像挺迷糊的,其实这个含义要 ...

  3. C++冷知识(1)

    func()等价于func(void) 也就是说在C++中,参数列表为空意味着不接受任何参数.之所以要注意这一点是因为在C语言中,参数列表为空意味着参数不确定.两者的语义是有巨大差别的,作为学了C再学 ...

  4. jmeter_02_目录文档说明

    jmeter目录文档说明 bin目录是可执行文件 jmeter.bat 是启动文件 可以启动jmeter. 使用notpad++ 等文本编辑器打开 bat文件 可以配置jvm的参数 比如堆内存[Hea ...

  5. redis6安装 centos系统

    Redis6 安装   在centos7.5服务器上按照官方发布的安装方式并不能进行正确的安装,现收集并整理如下安装方式,亲测有效 1.安装依赖 yum install -y cpp binutils ...

  6. linux(centos8):基于java13安装rocketmq-4.7.1(解决jdk不兼容的报错)

    一,Rocketmq是什么? 1, RocketMQ是一个队列模型的消息中间件,具有高性能.高可靠.高实时.分布式特点 相比kafka,rocketmq的实时性更强 2,官方网站: http://ro ...

  7. gin教程

    Golang Gin 实战(十)| XML渲染 Golang Gin 实战(九)| JSONP跨域和劫持 Golang Gin 实战(八)| JSON渲染输出 Golang Gin 实战(七)| 分组 ...

  8. 爬虫学习之-scrapy交互式命令 scrapy查看页面

    scrapy shell https:///www.baidu.com  会启动爬虫请求网页 view(response) 会在浏览器打开请求到的临时文件 response.xpath("/ ...

  9. 华为路由器配置OSPF

    OSPF是什么 OSPF(Open Shortest Pass First,开放最短路径优先协议),是一个最常用的内部网管协议,是一个链路状态协议. 使用场景:适用于运营商.政府机构等大型网络中多节点 ...

  10. js读取xml,javascript读取XML

    IE下示例代码: var xmlDoc = "<root><AlleyWay><Code>1103</Code><Name>胡同2 ...