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反射之获取类或接口上的所有方法及其注解(包括实现的接口上的注解) /** * 获取类或接口上的所有方法及方法上的注解(包括方法实现上的注解以及接口上的注解),最完整的工具类,没有现成的工具类 ...
随机推荐
- [啊哈!算法] 零基础彻底弄懂"并查集"
今天是算法数据结构专题的第5篇文章,我们一起来学习一下「并查集」. 并查集被很多ACMer认为是最简洁而优雅的数据结构之一,主要用于解决一些元素分组的问题.并支持两种操作: 合并(Union):把两个 ...
- L2-018 多项式A除以B (25 分) (math)
这仍然是一道关于A/B的题,只不过A和B都换成了多项式.你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数. 输入格式: 输入分两行,每行给出一个非零多项式,先给出A,再给出B.每行的 ...
- SCA技术进阶系列(三):浅谈二进制SCA在数字供应链安全体系中的应用
数字经济时代,随着开源应用软件开发方式的使用度越来越高,开源组件逐渐成为软件开发的核心基础设施,但同时也带来了一些风险和安全隐患.为了解决这些问题,二进制软件成分分析技术成为了一种有效的手段之一.通过 ...
- SpringCloud学习 系列八、OpenFeign
系列导航 SpringCloud学习 系列一. 前言-为什么要学习微服务 SpringCloud学习 系列二. 简介 SpringCloud学习 系列三. 创建一个没有使用springCloud的服务 ...
- 多倍图切图cutterman
- 第1篇 numpy 语法
import numpy as np A = np.array([ [1, 2, 3, 4], [5, 6, 7, 8], ], dtype=int) # dtype指定数据类型int float p ...
- AXI Channel
AXI Channel axi与ahb不同就是分为不同的channel write address channel - 表明一个transaction基本的属性,包含本次传输的地址\类型\大小(多少字 ...
- 【SHELL】反斜杠解决多个shell实例扩展
本意是想获取代码仓相对路径,代码如下 base_dir=`pwd` repo forall -c '{ user_dir=$(realpath --relative-to="$bas ...
- [转帖]深入JVM - Code Cache内存池
深入JVM - Code Cache内存池 1. 本文内容 本文简要介绍JVM的 Code Cache(本地代码缓存池). 2. Code Cache 简要介绍 简单来说,JVM会将字节码编译为本地机 ...
- [转帖]awk的printf格式化输出
https://www.cnblogs.com/chanix/p/12738097.html awk的printf格式化输出20121108 Chenxincat sort_result.txt223 ...