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反射之获取类或接口上的所有方法及其注解(包括实现的接口上的注解) /** * 获取类或接口上的所有方法及方法上的注解(包括方法实现上的注解以及接口上的注解),最完整的工具类,没有现成的工具类 ...
随机推荐
- 为什么加了@Transactional注解,事务没有回滚?
在昨天的<事务管理入门>一文发布之后,有读者联系说根据文章尝试,加了@Transactional注解之后,事务并没有回滚.经过一顿沟通排查之后,找到了原因,在此记录一下,给后面如果碰到类似 ...
- “n个球放到m个盒子”问题整理(Twelvefold way)
这个算法的正式名字是:"Twelvefold way",共用12种情况. 本文转载自:自为风月马前卒的博文:浅谈"n个球"和"m个盒子"之间 ...
- AtCoder Regular Contest 119 (ABC题)
比赛链接:Here A - 119 × 2^23 + 1 注意到 \(2^{60} > 10^{18}\) ,所以我们可以直接枚举 \(0\) ~ \(59\) int main() { ci ...
- CodeForces - 651A Joysticks ( 不难 但有坑 )
正式更换编译器为: VS Code 如何配置环境:click here 代码格式化工具:clang-format A. Joysticks 题目连接: http://www.codeforces.co ...
- zookeeper 特点、使用场景及安装,配置文件解析
本文为博主原创,未经允许不得转载: 1. Zookeeper 特点: ZooKeeper是用于分布式应用程序的协调服务.它公开了一组简单的API,分布式应用程序可以基于这些API用于同步,节点状态.配 ...
- 05-Shell索引数组变量
1.介绍 Shell 支持数组(Array),数组是若干数据的集合,其中的每一份数据都称为数组的元素. 注意Bash Shell 只支持一维数组,不支持多维数组. 2.数组的定义 2.1 语法 在 S ...
- 【MLA】内存泄漏检查
项目地址:skullboyer/MLA (github.com) 介绍 MLA 即 Memory Leak Analyzer,是一个排查内存泄漏的分析器 实现机制是在malloc时记录分配位置信息,在 ...
- [转帖]OpenSSL版本历史
OpenSSL版本历史 新闻日志 这是所有 OpenSSL 公告的简洁日志.它们几乎是发布通知. 日期物品 2021 年 7 月 29 日OpenSSL 3.0 的 Beta 2 现已推出.这是一个候 ...
- [转帖]clickhouse使用clickhouse-keeper代替zookeeper
目录 异常现象: 1. clickhouse的异常日志 2. 追踪对应节点的zookeeper日志 使用clickhouse-keeper代替 zookeeper的步骤: 1: 准备 clickhou ...
- [转帖]实战瓶颈定位-我的MySQL为什么压不上去
https://plantegg.github.io/2023/06/20/%E5%AE%9E%E6%88%98%E7%93%B6%E9%A2%88%E5%AE%9A%E4%BD%8D-%E6%88% ...