Java注解之获取注解内部数据的原因分析
我们都知道从JDK1.5开始,注解开始被支持使用,当我们在使用注解的时候感觉比配置文件用起来更加简便和清爽。配置文件是通过解析配置文件的内容获取到数据,那么为什么仅仅在类、方法或者属性上添加注解被注解对象就内部就能获取到注解内部的数据了呢?
一、给类添加单个注解
1、自定义一个注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Classname Pro
* @Description TODO
* @Date 2020/9/16 17:27
* @Created by Administrator
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
String className();
String methodName();
}
2、定义一个类用于测试类通过反射创建对象调用其内部方法

/**
* @Classname User
* @Description TODO
* @Date 2020/9/16 17:28
* @Created by Administrator
*/
public class User {
public void eat(){
System.out.println("吃饭...");
} public void drink(){
System.out.println("喝水...");
}
}
3、定义一个测试类用于测试注解内数据是如何被获取到的

import java.lang.reflect.Method; /**
* @Classname AnnotationClassTest
* @Description TODO
* @Date 2020/9/16 17:29
* @Created by Administrator
*/
@Pro(className = "User",methodName = "eat")
public class AnnotationClassTest {
public static void main(String[] args) throws Exception {
// 1 获取被注解位置的字节码对象
Class<AnnotationClassTest> testClass = AnnotationClassTest.class;
// 2 根据注解的字节码对象创建注解对象
Pro annotation = testClass.getAnnotation(Pro.class);
// 3 根据注解对象获取注解内部数据
String className = annotation.className();
String methodName = annotation.methodName();
// 3.1打印获取到的注解数据
System.out.println(className);
System.out.println(methodName);
// 4 通过反射通过获取到的className获取该类字节码对象
Class aClass = Class.forName(className);
// 5 通过该字节码对象根据获取到的methodName获取方法对象
Method method = aClass.getMethod(methodName);
// 6 通过类字节码对象生成该类对象
User user= (User) aClass.newInstance();
// 7 方法执行
method.invoke(user);
}
}
二、给方法添加单个注解
1、自定义一个注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Classname Pro
* @Description TODO
* @Date 2020/9/16 17:27
* @Created by Administrator
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro2 {
String className();
String methodName();
}
2、定义一个类用于测试类通过反射创建对象调用其内部方法

/**
* @Classname User
* @Description TODO
* @Date 2020/9/16 17:28
* @Created by Administrator
*/
public class User {
public void eat(){
System.out.println("吃饭...");
} public void drink(){
System.out.println("喝水...");
}
}
3、定义一个测试类用于测试注解内数据是如何被获取到的

import java.lang.annotation.Annotation;
import java.lang.reflect.Method; /**
* @Classname AnnotationClassTest
* @Description TODO
* @Date 2020/9/16 17:29
* @Created by Administrator
*/ public class AnnotationMethodTest {
@Pro2(className = "User",methodName = "eat")
public static void main(String[] args) throws Exception {
// 1 获取被注解位置的字节码对象
Class<AnnotationMethodTest> testClass = AnnotationMethodTest.class;
// 2 根据注解的字节码对象创建注解对象
Pro2 annotation = testClass.getMethod("main", String[].class).getAnnotation(Pro2.class);
// 3 根据注解对象获取注解内部数据
String className = annotation.className();
String methodName = annotation.methodName();
// 4 通过反射通过获取到的className获取该类字节码对象
Class aClass = Class.forName(className);
// 5 通过该字节码对象根据获取到的methodName获取方法对象
Method method = aClass.getMethod(methodName);
// 6 通过类字节码对象生成该类对象
User user= (User) aClass.newInstance();
// 7 方法执行
method.invoke(user);
}
}
三、给类添加多个注解
1、自定义两个注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Classname Pro
* @Description TODO
* @Date 2020/9/16 17:27
* @Created by Administrator
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
String className();
String methodName();
}
自定义注解1

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Classname Pro
* @Description TODO
* @Date 2020/9/16 17:27
* @Created by Administrator
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro3 {
String className();
String methodName();
String age();
}
自定义注解2
2、定义一个类用于测试类通过反射创建对象调用其内部方法

/**
* @Classname User
* @Description TODO
* @Date 2020/9/16 17:28
* @Created by Administrator
*/
public class User {
public void eat(){
System.out.println("吃饭...");
} public void drink(){
System.out.println("喝水...");
}
}
3、定义一个测试类用于测试注解内数据是如何被获取到的

import java.lang.reflect.Method; /**
* @Classname AnnotationClassTest
* @Description TODO
* @Date 2020/9/16 17:29
* @Created by Administrator
*/
@Pro(className = "User",methodName = "eat")
@Pro3(className = "User",methodName = "drink",age = "23")
public class AnnotationClassTest2 {
public static void main(String[] args) throws Exception {
// 1 获取被注解位置的字节码对象
Class<AnnotationClassTest2> testClass = AnnotationClassTest2.class;
Pro annotation = testClass.getAnnotation(Pro.class);
String className = annotation.className();
String methodName = annotation.methodName();
Class aClass = Class.forName(className);
Method method = aClass.getMethod(methodName);
User user= (User) aClass.newInstance();
method.invoke(user); Pro3 annotation2 = testClass.getAnnotation(Pro3.class);
String className2 = annotation2.className();
String methodName2 = annotation2.methodName();
Class aClass2 = Class.forName(className2);
Method method2 = aClass2.getMethod(methodName2);
User user2= (User) aClass2.newInstance();
method2.invoke(user2);
}
}
总结
之所以被注解内部能够获取注解内部数据根本原因就在于通过被注解对象字节码文件能够获取到该对象字节码文件中是否含有注解,并能够通过该字节码文件获取注解内部数据,因此更简便的实现了配置文件相同的功能。
Java注解之获取注解内部数据的原因分析的更多相关文章
- 用AOP拦截自定义注解并获取注解属性与上下文参数(基于Springboot框架)
目录 自定义注解 定义切面 获取上下文信息JoinPoint ProceedingJoinPoint 定义测试方法 测试结果 小结 AOP可以用于日志的设计,这样话就少不了要获取上下文的信息,博主在设 ...
- 使用C#利用cmd来调用java jar包获取其中的数据
其实也很简单,就是在C#中构建一个Process,启动jar包,并且给jar包传递参数 因为我并没有怎么学过JAVA,所以只写了个很小的Demo,就是根据传入的参数获取对应的数据 以下是JAVA De ...
- spring + mybatis 注解式事务不回滚的原因分析 @Transactional
在一个项目中发现spring的事务无法回滚. DEBUG: org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.ses ...
- C++ Win 32 使用原始套接字获取所有ip数据包并分析(包括ping包)
/*页面编码:GBK 开发环境 VS2019 */ #define _WINSOCK_DEPRECATED_NO_WARNINGS#include <iostream>#include&l ...
- 关于在Java中链接SQLServer数据库中失败的原因分析
首先声明:笔者是Java的初学者,并且一值是走在自学的道路上,长久以来只有“度娘”相伴.(加入了各种Java学习群,基本没有热心帮人解决问题的.可以理解-_-!!!)大神级的人物就不必看拙文了,没有什 ...
- java内存泄露/溢出等常见问题模拟及原因分析
Java 8:从持久代到metaspace 系统稳定性--OutOfMemoryError 常见原因及解决方法 java各种异常问题示例(附pdf下载): java.lang.OutOfMemoryE ...
- Jsoup获取全国地区数据(省市县镇村)
最近手头在做一些东西,需要一个全国各地的地域数据,从省市区到县镇乡街道的.各种度娘,各种谷歌,都没找到一个完整的数据.最后功夫不负有心人,总算找到一份相对来说比较完整的数据,但是这里的数据也只是精确到 ...
- SpringMVC_01 SpringMVC五大组件、SpringMVC编程步骤(不使用注解进行配置)、SpringMVC编程步骤(利用注解进行配置)、参数获取、响应数据
1 什么是SpringMVC 是一个mvc框架,用来简化基于mvc架构的web应用程序的 开发. 2 SpringMVC五大组件 DispatcherServlet (前端控制器) HanlderMa ...
- java反射获取注解并拼接sql语句
先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java. ...
- java反射之获取所有方法及其注解(包括实现的接口上的注解),获取各种标识符备忘
java反射之获取类或接口上的所有方法及其注解(包括实现的接口上的注解) /** * 获取类或接口上的所有方法及方法上的注解(包括方法实现上的注解以及接口上的注解),最完整的工具类,没有现成的工具类 ...
随机推荐
- Java | VS Code 如何导入外部 jar 包源
Java Extension Pack里的Project Manager for Java扩展,安装后在文档查看的下方会有"JAVA PROJECTS",在Referenced L ...
- normalize.css——移动端css初始化推荐
保护了有价值的默认值 修复了浏览器bug 是模块化的 拥有详细的文档 https://www.jianshu.com/p/9d7ff89757fd
- MINGW64 禁用 Bash 路径参数转换
MINGW64 可以让 Windows 无缝使用 Linux 命令,但是路径参数会被转换为 Windows 风格.例如: $ ./adb shell ls /system ls: C:/Program ...
- Canal使用和安装总结
转载请注明出处: 1.定义 Canal 组件是一个基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费,支持将增量数据投递到下游消费者(如 Kafka.RocketMQ 等)或者存储(如 El ...
- kafka常用操作
kafka运维常用查询操作总结以下几点: kafka生产和消费消息测试 发送:bin/kafka-console-producer.sh --broker-list 10.46.200.165:909 ...
- MCU芯片架构设计
目录 1.应用场景 主要是I2C\UART\SPI协议 2.Cortex-M3 MCU成本与工艺选型 按照晶圆进行收费,28nm,12寸晶圆,400万美金 晶圆是圆形的,die是方形的,会存在浪费 p ...
- 07-逻辑仿真工具VCS-Post processing with VCD+ files
逻辑仿真工具-VCS 编译完成不会产生波形,仿真完成之后,生成波形文件,通过dve产看波形 vcd是波形文件的格式,但是所占的内存比较大,后面出现了vpd(VCD+)波形文件 将一些系统函数嵌入到源代 ...
- 0xGame 2023【WEEK2】Crypto全解
中间的那个人 题目信息 from secret import flag from Crypto.Util.number import * from Crypto.Cipher import AES f ...
- 媒体查询常用 - 移动端和PC端尺寸
/* 移动端 */ @media all and (max-width: 768px) { } /* PC端 */ @media all and (min-width: 769px) { }
- js - 元素 scrollTop 设置无效的原因 及 解决办法
原因 : 元素 display : flex ; 解决方法 : display : block;