我们都知道从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注解之获取注解内部数据的原因分析的更多相关文章

  1. 用AOP拦截自定义注解并获取注解属性与上下文参数(基于Springboot框架)

    目录 自定义注解 定义切面 获取上下文信息JoinPoint ProceedingJoinPoint 定义测试方法 测试结果 小结 AOP可以用于日志的设计,这样话就少不了要获取上下文的信息,博主在设 ...

  2. 使用C#利用cmd来调用java jar包获取其中的数据

    其实也很简单,就是在C#中构建一个Process,启动jar包,并且给jar包传递参数 因为我并没有怎么学过JAVA,所以只写了个很小的Demo,就是根据传入的参数获取对应的数据 以下是JAVA De ...

  3. spring + mybatis 注解式事务不回滚的原因分析 @Transactional

    在一个项目中发现spring的事务无法回滚. DEBUG: org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.ses ...

  4. C++ Win 32 使用原始套接字获取所有ip数据包并分析(包括ping包)

    /*页面编码:GBK 开发环境 VS2019 */ #define _WINSOCK_DEPRECATED_NO_WARNINGS#include <iostream>#include&l ...

  5. 关于在Java中链接SQLServer数据库中失败的原因分析

    首先声明:笔者是Java的初学者,并且一值是走在自学的道路上,长久以来只有“度娘”相伴.(加入了各种Java学习群,基本没有热心帮人解决问题的.可以理解-_-!!!)大神级的人物就不必看拙文了,没有什 ...

  6. java内存泄露/溢出等常见问题模拟及原因分析

    Java 8:从持久代到metaspace 系统稳定性--OutOfMemoryError 常见原因及解决方法 java各种异常问题示例(附pdf下载): java.lang.OutOfMemoryE ...

  7. Jsoup获取全国地区数据(省市县镇村)

    最近手头在做一些东西,需要一个全国各地的地域数据,从省市区到县镇乡街道的.各种度娘,各种谷歌,都没找到一个完整的数据.最后功夫不负有心人,总算找到一份相对来说比较完整的数据,但是这里的数据也只是精确到 ...

  8. SpringMVC_01 SpringMVC五大组件、SpringMVC编程步骤(不使用注解进行配置)、SpringMVC编程步骤(利用注解进行配置)、参数获取、响应数据

    1 什么是SpringMVC 是一个mvc框架,用来简化基于mvc架构的web应用程序的 开发. 2 SpringMVC五大组件 DispatcherServlet (前端控制器) HanlderMa ...

  9. java反射获取注解并拼接sql语句

    先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java. ...

  10. java反射之获取所有方法及其注解(包括实现的接口上的注解),获取各种标识符备忘

    java反射之获取类或接口上的所有方法及其注解(包括实现的接口上的注解) /** * 获取类或接口上的所有方法及方法上的注解(包括方法实现上的注解以及接口上的注解),最完整的工具类,没有现成的工具类 ...

随机推荐

  1. 灵魂拷问std::enable_shared_from_this,揭秘实现原理

    参考博客: std::enable_shared_from_this原理浅析 引言 在C++编程中,使用智能指针是一种安全管理对象生命周期的方式.std::shared_ptr是一种允许多个指针共享对 ...

  2. POJ:Arbitrage (搜索,汇率换算是否赚?)

    POJ 2240 http://poj.org/problem?id=2240 题意:判断是否存在使得汇率增多的环 [任意一个点的汇率增多都可以] Floyd 简单变形 \(w[i][j] = max ...

  3. 2018年第九届 蓝桥杯A组 C/C++决赛题解

    蓝桥杯历年国赛真题汇总:Here 1.三角形面积 已知三角形三个顶点在直角坐标系下的坐标分别为: (2.3, 2.5) (6.4, 3.1) (5.1, 7.2) 求该三角形的面积. 注意,要提交的是 ...

  4. 领域驱动设计(DDD)实践之路(三):如何设计聚合

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/oAD25H0UKH4zujxFDRXu9Q作者:wenbo zhang [领域驱动设计实践之路 ...

  5. SPI 在 Dubbo中 的应用

    通过本文的学习,可以了解 Dubbo SPI 的特性及实现原理,希望对大家的开发设计有一定的启发性. 一.概述 SPI 全称为 Service Provider Interface,是一种模块间组件相 ...

  6. P2895(未解决)

    这是一道略复杂的常规BFS题,但我想用DFS来解决,结果写出代码却总是主函数异常返回,不知哪里错了,检查半天也没发现,以后再看看吧. Code #include<iostream> #in ...

  7. freeswitch的任务引擎问题与解决方案

    概述 freeswitch核心框架中有一个定时任务系统task,在开发过程中用来做一些延时操作和异步操作很方便. 我们在VOIP的呼叫流程中,经常会有一些对实时性要求没那么高的操作,或者会有阻塞流程的 ...

  8. hdu 5234

    题意:求在不超过k的情况下,最多可以得到多少价值. 三维dp,结合01背包,第三维就是用来保存在不同的背包容量下能得到的最大价值,也就是第三维有很多状态. #include<iostream&g ...

  9. Nacos源码 (3) 注册中心

    本文将从一个服务注册示例入手,通过阅读客户端.服务端源码,分析服务注册.服务发现原理. 使用的2.0.2的版本. 客户端 创建NacosNamingService对象 NacosNamingServi ...

  10. [转帖]Docker最佳实践:5个方法精简镜像

    https://juejin.cn/post/6844903880526921741   精简Docker镜像的好处很多,不仅可以节省存储空间和带宽,还能减少安全隐患.优化镜像大小的手段多种多样,因服 ...