1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

springboot自定义注解

springboot自定义注解

注解(Annotation)对做java开发的小伙伴肯定不陌生,不能说熟悉,但一定在学习或者做项目的过程中有所耳闻,特别是随着springboot框架的大火,“约定大于配置”的开发理念被越来越多的人所喜爱。当然使用注解的最重要的好处就是减少代码的侵入,降低系统耦合性,当然就这一个理由就足够了。

在没有详细了解注解,没有自己定义注解,没有应用自定义注解之前,我对注解的认知仅仅停留在它是一种标记,特别是在springboot中,通过注解我们可以免去繁琐的配置过程,简化开发流程,但现在我发现自定义注解如果真的用的好,可以解决很多实际开发过程中的痛点、难点,让我们可以提出更多更合理的非侵入式解决方案,比如方法的鉴权、多数据源的数据源选择。好了,这里我们先不多说了,开始正文。

什么是注解

这里要多说些,介绍下注解的一些情况。注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记。标记可以加在包、类、属性、方法、方法的参数以及局部变量上。通过反射可以拿到类、方法、变量上的注解。我们随便打开一个注解,比如springboot里面的Configuration注解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";

    boolean proxyBeanMethods() default true;
}

根据上面的代码,我们可以得出以下结论:

  • 创建注解的关键字是@interface
  • 注解上也可以加注解
  • 注解可以有属性

但注解上加的都是什么注解,都有什么含义呢?这里要引入注解的一个概念——元注解。所谓元注解就是声明在注解上的注解,元注解是注解的一种声明,元注解分别有以下五种:

  • @Retention:保留期,声明注解的存活时间
    • RetentionPolicy.SOURCE:仅源代码时保留,在编译时会被丢弃忽略
    • RetentionPolicy.CLASS:编译为class时保留,但不会被加载到jvm中
    • RetentionPolicy.RUNTIME:运行环境保留,会被加载到jvm中
  • @Documented:保留本类中的注解并能够被javadoc识别
  • @Target:指定注解的添加位置(类/方法/变量等)
    • ElementType.TYPE:类注解
    • ElementType.FIELD:字段注解
    • ElementType.METHOD:方法注解
    • ElementType.PARAMETER:方法内的参数注解
    • ElementType.CONSTRUCTOR:构造方法注解
    • ElementType.LOCAL_VARIABLE:局部变量注解
    • ElementType.ANNOTATION_TYPE:注解注解
    • ElementType.PACKAGE:包注解
    • ElementType.TYPE_PARAMETER
    • ElementType.TYPE_USE
  • @Inherited:注解是否能够被子类继承

注解的介绍就到这里,我们继续往下看。

创建springboot项目

这里其实我不想介绍太多,因为我觉得这些都是很基础的东西,应该是每个小伙伴都会的,但考虑到还有一些小伙伴处在初学阶段,所以我还是会贴出我的项目结构,方便这些小伙伴参考:

首先是项目结构

pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>io.github.syske</groupId>
    <artifactId>custom-annotation-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>custom-annotation-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.61</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

自定义注解

根据我们注解的介绍,我们在声明注解的时候必须用到元注解,否则这个注解是没有任何意义的。开始定义我们的第一个注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckAuth {
}

这样我们的第一个注解就定义好了,包含了两个元注解,一个指明注解的类型,一个指明注解的生存时间,是不是很简单,接下来,我们要开始使用我们的注解。

自定义注解应用

我先说下本次示例注解的应用思路:我刚定义的注解是为了方法鉴权操作,所以我把刚定义的注解加在需要进行鉴权操作的方法上,然后定义一个拦截器,拦截器的拦截规则设置为拦截所有,然后在拦截器内进行判断和校验,如果方法有鉴权注解,则进行鉴权操作,否则跳过,具体如下:

拦截器

public class AuthenticationInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            if (handlerMethod.hasMethodAnnotation(CheckAuth.class)) {
                System.out.println("有CheckAuth注解");
                String token = request.getParameter("token");
                if (!"ABCDEF12345".equals(token)) {
                    throw new AuthException();
                }
            }
        }
        return true;
    }
}

拦截器配置:

 // 鉴权拦截器
registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/**");

这里最核心的操作是handlerMethod.hasMethodAnnotation(CheckAuth.class),即判断当前方法是否有CheckAuth.class注解。

当然从handler中获取方法也是很重要的一个操作,我们只有从handler中拿到方法,才能判断该方法是否有我们自定义的注解。我们先来看下handler都有哪些类型:

  • HandlerMethod:方法
  • ResourceHttpRequestHandler:静态资源

根据目前掌握的资料,我还没发现其他类型的handler,后面发现了再补充。

总结

好了,今天的内容就到这里,核心内容就是学会自定义注解,然后可以应用自定义注解解决问题。今天提供的思路就是通过自定义注解实现拦截器解耦,即新增方法后只需要在方法上增加鉴权注解即可,无需修改拦截器配置。某个方法不想鉴权,仅需要去掉方法上的鉴权注解即可。好了,大家周末愉快哦!!!

posted @ 2020-08-02 16:25  云中志  阅读(526)  评论(0编辑  收藏  举报