撸撸java注解

手写 Mybatis,“整整” Mybatis源码 前言 前两天写了一个 手写Spring ioc 框架,“撸撸”Spring 源码我们今天来整整Mybatis。 mybaits 在 ORM 框架中,可算是半壁江山了,由于它是轻量级,半自动加载,灵活性和易拓展性。深受广大公司的喜爱,所以我们程序开发也离不开 mybatis 。 很多朋友对 mybatis 源码没什么了解,或者想看但是不知道怎么看的苦恼吗? 归根结底,我们还是需要知道为什么会有 mybatis ,mybatis 解决了什么问题? 想要知道 mybatis 解决了什么问题,就要知道传统的 阅读详情
AI摘要

本文详细介绍了Java注解的组成部分,包括Annotation、ElementType和RetentionPolicy的使用。通过具体示例展示了如何在反射中使用注解,以及如何自定义注解模拟SpringMVC的RequestMapping功能。

Annotation 组成部分

Annotation.java

package java.lang.annotation;
public interface Annotation {

    boolean equals(Object obj);

    int hashCode();

    String toString();

    Class<? extends Annotation> annotationType();
}

ElementType.java

package java.lang.annotation;

public enum ElementType {
    TYPE,               /* 类、接口(包括注释类型)或枚举声明  */

    FIELD,              /* 字段声明(包括枚举常量)  */

    METHOD,             /* 方法声明  */

    PARAMETER,          /* 参数声明  */

    CONSTRUCTOR,        /* 构造方法声明  */

    LOCAL_VARIABLE,     /* 局部变量声明  */

    ANNOTATION_TYPE,    /* 注释类型声明  */

    PACKAGE             /* 包声明  */
}

RetentionPolicy.java

package java.lang.annotation;
public enum RetentionPolicy {
    SOURCE,            /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了  */

    CLASS,             /* 编译器将Annotation存储于类对应的.class文件中。默认行为  */

    RUNTIME            /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
}

注解类

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation1 {
}

在反射中使用 Annotation

在反射的 Class, Method, Field 等函数中,有许多于 Annotation 相关的接口。

这也意味着,我们可以在反射中解析并使用 Annotation。

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Annotation在反射函数中的使用示例
 */
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String[] value() default "unknown";
}


public class Person {

    /**
     * empty()方法同时被 "@Deprecated" 和 "@MyAnnotation(value={"a","b"})"所标注
     * (01) @Deprecated,意味着empty()方法,不再被建议使用
     * (02) @MyAnnotation, 意味着empty() 方法对应的MyAnnotation的value值是默认值"unknown"
     */
    @MyAnnotation
    @Deprecated
    public void empty(){
        System.out.println("\nempty");
    }

    /**
     * sombody() 被 @MyAnnotation(value={"girl","boy"}) 所标注,
     * @MyAnnotation(value={"girl","boy"}), 意味着MyAnnotation的value值是{"girl","boy"}
     */
    @MyAnnotation(value={"girl","boy"})
    public void somebody(String name, int age){
        System.out.println("\nsomebody: "+name+", "+age);
    }
}



import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class AnnotationTest {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 新建Person
        Person person = new Person();
        // 获取Person的Class实例
        Class<Person> c = Person.class;
        // 获取 somebody() 方法的Method实例
        Method somebody = c.getMethod("somebody", new Class[]{String.class, int.class});

        // 执行该方法
        somebody.invoke(person, new Object[]{"lily", 18});
        iteratorAnnotations(somebody);

        // 获取 somebody() 方法的Method实例
        Method mEmpty = c.getMethod("empty", new Class[]{});
        // 执行该方法
        mEmpty.invoke(person, new Object[]{});
        iteratorAnnotations(mEmpty);

    }

    private static void iteratorAnnotations(Method somebody) {
        if (somebody.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = somebody.getAnnotation(MyAnnotation.class);
            String[] values = annotation.value();
            for (String str : values)
                System.out.printf(str + ", ");

        }
    }


}

自定义注解使用案例1-模拟springmvc的requestMapping注解

package springmvc;

import java.lang.reflect.Method;

public class ParserResult {
    private String path;
    private String classpath;
    private Method method;

    public String getPath() {
        return path;
    }

    public Method getMethod() {
        return method;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    public String getClasspath() {
        return classpath;
    }

    public void setClasspath(String classpath) {
        this.classpath = classpath;
    }
}
package springmvc;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@interface RequestMapping {
    String path() default "";
}
package springmvc;
@RequestMapping(path="/root")
public class RequestMappingObject {
    @RequestMapping(path = "method1")
    public void method1(){

    }

    @RequestMapping(path = "method2")
    public void method2(){

    }

    @RequestMapping(path = "method3")
    public void method3(){

    }
}
package springmvc;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class RequestMappingParser<T> {
    private final Class<T> tClass;

    public RequestMappingParser(Class<T> tClass) {
        this.tClass = tClass;
    }

    public List<ParserResult> parse() {
        Package packages = tClass.getPackage();
        //反射获取类的注解路径
        RequestMapping annotationField = tClass.getAnnotation(RequestMapping.class);
        String rootPath = annotationField != null ? annotationField.path() : "";
        if (!rootPath.startsWith("/")) {
            rootPath = "/";
        }
        //反射或者所有的方法
        List<ParserResult> list = new ArrayList<ParserResult>();
        Method[] methods = this.tClass.getMethods();
        for (Method method : methods) {
            ParserResult parserResult = new ParserResult();
            if (method == null) {
                continue;
            }
            RequestMapping annotation = method.getAnnotation(RequestMapping.class);
            if (annotation == null) {
                continue;
            }
            String path = annotation.path();
            if ("".equals(path)) {
                continue;
            }
            if(path.startsWith("/")){
                parserResult.setPath(rootPath+path);
            }else{
                parserResult.setPath(rootPath+"/"+path);
            }
            Class<?> declaringClass = method.getDeclaringClass();
            String declaringClassName = declaringClass.getName();
            parserResult.setClasspath(declaringClassName);
            list.add(parserResult);
        }
        return list;

    }

}
package springmvc;

import com.alibaba.fastjson.JSONObject;

import java.util.List;

public class RequetMappingTest {
    public static void main(String[] args) {
        RequestMappingParser requestMappingParser = new RequestMappingParser(RequestMappingObject.class);

        List parse = requestMappingParser.parse();
        System.out.println(JSONObject.toJSONString(parse));
    }
}
打怪上分! 手写Spring ioc 框架,狠狠的“撸撸”Spring 源码 估计很多朋友使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过。 你是不是有这样的感觉呢? 但是 spring 源码存在一个问题,那就是过于抽象,导致学习起来成本上升。所以本文由浅入深,只实现 spring 的核心功能,便于自己和他人学习 spring 的核心原理。 文章有点长,耐心阅读!如果对你有帮助,记得三连哦! spring 的核心 Spring 的核心就是 spring-beans,后面的一切 spring-boot,spring-cloud 阅读详情

相关推荐

不羞涩社区图片爬取,我真的不是为了看小姐姐私照,从未这么渴望过知识!

不羞涩社区图片爬取展示效果请求头获取网站的请求数据提取数据保存数据完整代码 展示效果 PS:仅供学习交流,侵删。 请求头 我下面就不一一解释了,小白没有基础的看不懂没关系,拿代码是可以直接运行的了,至于懂的也都懂了,没有基础的朋友建议可以从Python基础开始看看,我专栏也有写过Python基础的内容,感兴趣的话自己去看看吧。 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53

weixin_56957149的博客 4万+

190行LUA撸撸撸了一天。

这是我一天的战果,几乎每一个函数都会碰到问题,这里撸撸那里撸撸,结果,一天的时候只撸了190行。不过还好,功能都实现了。。。local MainScene = class("MainScene", cc.load("mvc").ViewBase)local bg local bg1 local bgWidth = 0 local bgHeight = 0 local bgMoveSpeed = 2.

severnth 2万+

教妹学 Java:撸个注解有什么难的

“二哥,这节讲注解吗?”三妹问。 “是的。”我说,“注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。@Override 注解用过吧?但你知道怎么自定义一个注解吗?” 三妹毫不犹豫地摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。 “好吧,哥来告诉你吧。” 注解(Annotation)是在 Java 1.5 时引入的概念,同 class 和 interface 一样,也属于一种类型。注解提供了一系列数据用来装饰程序代码(类、方法、

沉默王二 2365

OSChina 周六乱弹 —— 尺度极高,少儿不宜!

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33788244的博客 8545

Ansys Lumerical 启动时出现 Error: Could not connect to Ansys license server specified at 1055@ 的另一种解决办法

昨天在关闭了中之后 就能正常打开 FDTD 了,结果今天想开启出现了同样的报错:我猜测昨天能启动的原因在于关闭之后要重启电脑,并且在重启之后我第一时间打开 lumerical 测试因此端口没有被占用,今天是在电脑启动之后一段时间才打开所以又遇到了端口占用的问题。

qq_51404184的博客 9545

Android Camera性能优化概述

做camera性能优化方面的工作有几年了,想写一篇文章简单介绍一下其中涉及到的具体技术,这篇文章会大概介绍一下涉及到的技术。

weixin_42136255的博客 4023

手撸Java注解的注入实现过程

在Spring中使用注解,极大的减少了配置各种xml文件的反复操作,一个小小的注解就能够有如此强大的功能不经让人感慨。那注解是依靠那种机制将数据注入到我们的类中的呢?答案是反射机制。本文将自定义一个注解类,不依靠Spring,借助java的原生方法,手撸一个注解注入的实现过程。 自定义一个注解类 自定义接口及其实现类 创建工厂方法并实现注解的注入 测试 结果输出: ...

whgtheone的博客 2145

极速建站!用1Panel面板一键部署Halo博客的保姆级教程 | 企业官网/个人博客搭建教程

个人博客是一种在互联网上发布自己的文章、图片、视频等内容的平台,通常以文字为主要形式,但也可以包含其他媒体。个人博客的用途非常广泛。它可以用来记录博主的日常生活、分享自己的知识和经验、展示自己的作品和技能,以及交流自己的观点和看法。通过个人博客,博主可以与读者建立联系,分享自己的见解和体验,同时也可以从读者那里获得反馈和建议。

zeruns的博客 1831

深入理解Java高级特性——注解

博主在初学注解的时候看到网上的介绍大部分都是直接介绍用法或者功能,没有实际的应用场景,篇幅又很长导致学习的时候难以理解其意图,而且学完就忘QAQ。本篇文章中我将结合实际的应用场景尽可能由浅入深,平缓的介绍java注解。 java注解是jdk1.5以后新出的特性,对于它的应用非常广泛,我们首先来看一下注解的应用,百度百科上这样说: 我们可以看到,注解的作用有三方面: 编写doc文档:这个就我们很常...

weixin_44782075的博客 228

Xilinx Vitis 2020.1中Microblaze SREC SPI Bootloader初始化失败的调试与修复指南

本文详细解析了在Xilinx Vitis 2020.1开发环境中,Microblaze SREC SPI Bootloader初始化失败的常见原因与解决方案。核心问题通常源于Flash上电时序或软件配置,如`serial_flash_family`参数未生效、链接脚本设置不当或BRAM初始化文件选择错误。文章提供了从硬件配置检查、工程设置修正到代码级添加重试机制的完整调试路径,帮助开发者快速定位并修复启动故障,确保系统稳定启动。

weixin_29163857的博客 186

通达信+大智慧数据同步存调DLL

数据同步存调DLL(通达信版+大智慧版)

guleba的博客 2050

Java高级特性——注解,这也许是最简单易懂的文章了

最近,浪尖在做flink的项目时source和sink的绑定那块用到了注解,当然新版本1.6以后就变为server load的方式加载。但是浪尖也是觉得很有毕业讲一下注解...

大数据星球-浪尖 370

海康DS-7604N-K1/RTB固件包

【摘要】海康DS-7604N-K1/RTB萤石云设备发布V4.30.091版本升级程序(2022.09.19),仅适用于指定型号。升级前需先升级至V3.4.106基础版本,刷机会重置设备为未激活状态,需重新设置admin密码。该机型支持密码/手势登录,无密码时可通过U盘升级。注意事项:升级存在风险,需确认程序适用性;升级过程严禁断电;必须阅读压缩包内的刷机说明。此为定制机型,非必要不建议升级。(150字)

海康威视技术支持 1570

好了,这次我真的不装了,撸个注解有什么难的!

注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。@Override 注解用过吧?@Service注解用过吧?但你知道怎么自定义一个注解吗? 恐怕你会摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。 01、注解是什么 注解(Annotation)是在 Java 1.5 时引入的概念,同 class 和 interface...

weixin_46898270的博客 323

Unity 横版游戏开发天花板?状态机、联机同步与横版动作游戏架构全都有

在 Unity 横版动作游戏开发领域,最耗时间的往往不是角色移动,而是整套“可扩展架构”的搭建。包括角色状态管理、敌人 AI、武器系统、关卡编辑器、联机同步、输入适配、UI 与存档系统等。2D Action Platformer Kit 的核心价值,并不只是“提供素材”,而是它已经帮开发者搭好了一整套适用于横版动作游戏的底层框架。

2403_88403568的博客 424

继电器控制LED灯具导致触点烧蚀粘连的解决办法

继电器控制LED灯具导致触点烧蚀粘连的解决办法

2700

不吹牛逼,撸个注解有什么难的

注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。@Override 注解用过吧?@Service 注解用过吧?但你知道怎么自定义一个注解吗? 恐怕你会摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。 01、注解是什么 注解(Annotation)是在 Java 1.5 时引入的概念,同 class 和 interfac...

沉默王二 6939

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

撸个注解有什么难的 请看这里

01、注解是什么 注解(Annotation)是在 Java 1.5 时引入的概念,同 class 和 interface 一样,也属于一种类型。注解提供了一系列数据用来装饰程序代码(类、方法、字段等),但是注解并不是所装饰代码的一部分,它对代码的运行效果没有直接影响(这句话怎么理解呢?),由编译器决定该执行哪些操作。 来看一段代码,我随便写的,除了打印到控制台的那句宣传语,其他都不重要,嘻嘻...

wangrui813的博客 1930

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

撸个注解

目录撸个注解注解是什么注解的生命周期注解修饰的目标开始撸注解使用注解测试注解最后 撸个注解 ​ 注解是java中十分重要的一部分,我们无时无刻都在使用这他,尤其是使用Spring框架开发的时候,但是如何自定义一个注解呢,或者注解到底是如何生效的呢,工作原理是什么呢?接下来我们就一起动手撸一个注解 注解是什么 ​ 注解是Java1.5时引入的概念,属于一种类型。注解提供了一系列数据用来修饰程序代码(类、方法、字段),但是注解并不是所修饰代码的一部分,即它对代码的运行没有直接影响,由编译器决定该执行那些操作 注

冢狐的私人空间 571

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【手撸IM】非 Springboot 项目实现自定义注解 Bean 注入

介绍如何使用自定义注解在非 Spring Boot 项目中实现 Bean 自动注入及管理。

bossfriday - 个人博客 967

@jsonfield注解_好了,不装了,撸个注解有什么难的!

注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。@Override 注解用过吧?@Service注解用过吧?但你知道怎么自定义一个注解吗?恐怕你会摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。01、注解是什么注解(Annotation)是在 Java 1.5 时引入的概念,同 class 和 interface 一样,...

weixin_39530557的博客 114

手撸注解框架 —— 仿 Retrofit

前言说起注解框架,不得不说的是 ButterKnife,Retrofit,还有 Dagger。想来全是 Square 公司的作品,不由得心生膜拜。。。最近一直在用 ButterKnife,看了下源码也有一些感悟。人家大神写代码就是高大上,就为了省一行代码 findViewById(),硬生生撸了一个库出来。。。 以前没感觉,现在感觉注解真 TM 好用。俺也要用注解省代码!!! 项目地址项目完整代

fashare 的博客 2146

@jsonfield注解_不吹牛逼,撸个注解有什么难的

来自公众号:沉默王二注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。@Override 注解用过吧?@Service 注解用过吧?但你知道怎么自定义一个注解吗?恐怕你会摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。01、注解是什么注解(Annotation)是在 Java 1.5 时引入的概念,同 class...

weixin_39633276的博客 193
上一篇: 前端学习-超强VUE教程02
下一篇: 前端学习-超强VUE教程08
沐果果
博客等级 码龄10年 19粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值