Spring Boot 2 实践记录之 组合注解原理
Spring 的组合注解功能,网上有很多文章介绍,不过都是介绍其使用方法,鲜有其原理解析。
组合注解并非 Java 的原生能力。就是说,想通过用「注解A」来注解「注解B」,再用「注解B」 来注解 C(类或方法),就能够使 C 同时拥有「注解A」和「注解B」是行不通的。
示例如下:
先定义注解 SuperAnno:
import java.lang.annotation.*; @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SuperAnno {
}
再定义注解 SubAnno,并使用 SuperAnno 注解 SubAnno:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SuperAnno
@SomeAnno
public @interface SubAnno {
}
定义 Test,使用 SubAnno 注解 Test:
@SubAnno
public class Test { }
测试一下,看看我们能不能拿到 Test 的 SuperAnno 注解:
import java.lang.annotation.Annotation;
public class Main {
public static void main(String[] args) {
// write your code here
Test test = new Test();
Class<?> cl = test.getClass();
Annotation[] annotations = cl.getAnnotations();
for(Annotation annotation: annotations) {
System.out.println(annotation.annotationType());
}
}
}
打印出来的结果为:
interface com.company.SubAnno
唔,SuperAnno 没有出现。
怎么拿到合并的注解呢?
核心的思路就是拿到注解后,递归获取其上的注解,见下例:
import javax.annotation.*;
import java.lang.annotation.*;
import java.util.ArrayList; public class Main { private ArrayList<Annotation> annos = new ArrayList<>(); public static void main(String[] args) {
// write your code here
Test test = new Test();
Class<?> cl = test.getClass();
Main main = new Main();
main.getAnnos(cl);
for(Annotation anno: main.annos) {
System.out.println(anno.annotationType());
}
} private void getAnnos(Class<?> cl) {
Annotation[] annotations = cl.getAnnotations();
for(Annotation annotation: annotations) {
if (annotation.annotationType() != Deprecated.class &&
annotation.annotationType() != SuppressWarnings.class &&
annotation.annotationType() != Override.class &&
annotation.annotationType() != PostConstruct.class &&
annotation.annotationType() != PreDestroy.class &&
annotation.annotationType() != Resource.class &&
annotation.annotationType() != Resources.class &&
annotation.annotationType() != Generated.class &&
annotation.annotationType() != Target.class &&
annotation.annotationType() != Retention.class &&
annotation.annotationType() != Documented.class &&
annotation.annotationType() != Inherited.class
) {
annos.add(annotation);
getAnnos(annotation.annotationType());
}
}
}
}
Spring Boot 2 实践记录之 组合注解原理的更多相关文章
- Spring Boot 2 实践记录之 使用 ConfigurationProperties 注解将配置属性匹配至配置类的属性
在 Spring Boot 2 实践记录之 条件装配 一文中,曾经使用 Condition 类的 ConditionContext 参数获取了配置文件中的配置属性.但那是因为 Spring 提供了将上 ...
- Spring Boot 2 实践记录之 MyBatis 集成的启动时警告信息问题
按笔者 Spring Boot 2 实践记录之 MySQL + MyBatis 配置 中的方式,如果想正确运行,需要在 Mapper 类上添加 @Mapper 注解. 但是加入此注解之后,启动时会出现 ...
- Spring Boot 2 实践记录之 封装依赖及尽可能不创建静态方法以避免在 Service 和 Controller 的单元测试中使用 Powermock
在前面的文章中(Spring Boot 2 实践记录之 Powermock 和 SpringBootTest)提到了使用 Powermock 结合 SpringBootTest.WebMvcTest ...
- Spring Boot 2 实践记录之 Powermock 和 SpringBootTest
由于要代码中使用了 Date 类生成实时时间,单元测试中需要 Mock Date 的构造方法,以预设其行为,这就要使用到 PowerMock 在 Spring Boot 的测试套件中,需要添加 @Ru ...
- Spring Boot 2 实践记录之 Redis 及 Session Redis 配置
先说 Redis 的配置,在一些网上资料中,Spring Boot 的 Redis 除了添加依赖外,还要使用 XML 或 Java 配置文件做些配置,不过经过实践并不需要. 先在 pom 文件中添加 ...
- Spring Boot 2 实践记录之 使用 Powermock、Mockito 对 UUID 进行 mock 单元测试
由于注册时,需要对输入的密码进行加密,使用到了 UUID.sha1.md 等算法.在单元测试时,使用到了 Powermock,记录如下. 先看下加密算法: import org.apache.comm ...
- Spring Boot 2 实践记录之 MySQL + MyBatis 配置
如果不需要连接池,那么只需要简单的在pom文件中,添加mysql依赖: <dependency> <groupId>mysql</groupId> <arti ...
- Spring Boot 2 实践记录之 条件装配
实验项目是想要使用多种数据库访问方式,比如 JPA 和 MyBatis. 项目的 Service 层业务逻辑相同,只是具体实现代码不同,自然是一组接口,两组实现类的架构比较合理. 不过这种模式却有一个 ...
- Spring Boot 最核心的 25 个注解,都是干货!
学习和应用 Spring Boot 有一些时间了,你们对 Spring Boot 注解了解有多少呢?今天栈长我给大家整理了 Spring Boot 最核心的 25 个注解,都是干货! 你所需具备的基础 ...
随机推荐
- centos 6.5 ftp服务配置及客户端使用
一.ftp服务简介 FTP是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”.用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(Ap ...
- OC 和 swift 冒泡排序
swift 版 var numbers = [17, 28, 36, 15, 39] print("排序前\(numbers)") for i in 0..<numbers. ...
- Html的Padding,Margin自己理解图
Html的Padding,Margin自己理解图.
- 开发中经典sql总结
1.说明:显示文章.提交人和最后回复时间 select a.title,a.username,b.adddate ,(select max(adddate) from table where tabl ...
- 欲哭无泪的p-value = 0.051 | 做几次重复能得到较低的p-value
欲哭无泪的p-value = 0.051 | 做几次重复能得到较低的p-value 已有 1469 次阅读 2017-12-15 14:12 |个人分类:RNA-seq|系统分类:科普集锦|关键词:R ...
- 洛谷 P2986 [USACO10MAR]伟大的奶牛聚集(树形动规)
题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...
- ShowMsg函数
ShowMsg():显示提示信息,跳转到相应页面 例子: ShowMsg(,);
- 前后台交互(打开前端页面,不传递任何数据,发送ajax请求)
1.打开前端,不传递任何数据 <script src="./jquery.min.js"></script> <script> $(docume ...
- 7. Debug on local machine
Step 1:
- 使用JConsole监控HBase内存状态
使用JConsole或者VisualVM等工具监控HBase状态时,需要修改HBase的配置文件,以解决随机端口问题. 文件名:hbase-env.sh export HBASE_JMX_BASE=& ...