aop实现自定义注解

news2024/12/24 2:31:10

注解简单知识

关键字

自定义注解的关键字是@interface

参数类型

自定义注解的参数类型:八大基础类型、String、枚举、注解,还可以是以上类型对应的数组

如果只有一个成员变量,名字叫value

注解赋值

如果定义了成员变量,必须要给成员变量赋值 @MyAnnotation(value="")

如果只有一个成员变量,且成员变量的名称是value,可以省略value@MyAnnotation("")

如果成员变量给定默认值,可以不用再次赋值

一个注解的内部可以不定义成员变量的(@override)

定义了成员变量的注解叫元数据

没有定义成员变量的注解叫标记

元注解

用于修饰其他注解的注解

@Retention

值是一个枚举类型

 用于声明生命周期

SOURCE:生命周期只在源文件中,编译器直接丢弃这种策略的注释,在.class文件中不会保留注解信息

CLASS:在字节码文件中有效,默认

RUNTIME:运行时有效,当运行Java程序时,JVM会保留注释,加载在内存中,程序可以通过反射获取该注释

@TARGET

用于指定被修饰的注解能用于修饰哪些程序元素

包含一个value的成员变量

 值

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Document

用于指定被该元注解修饰的注解类将被javadoc工具提取成文档。默认情况下,javadoc时不包括注解的,但是加上了这个注解生成的文档中就带着注解了

Document注解修饰了Deprecated注解,那么 Deprecated注解就会在javadoc提取的时候,提取到API中

@Inherited

被它修饰的注解具有继承性,如果有个类使用了被@Inherited修饰的注解,那么它的子类也将具有该注解

aop实现自定义注解

添加依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

写需要的注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {

    /** 请求类型 */
    String reqType();
    /** 接口类型 */
    String apiType();
}

定义切面

@Aspect
@Component
public class LogAspect {

    @Around("@annotation(logAnnotation)")
    public Object around(ProceedingJoinPoint point, LogAnnotation logAnnotation) throws Throwable{
        // 类名
        String className = point.getTarget().getClass().getName();
        // 方法名
        String methodName = point.getSignature().getName();
        // 开始时间
        long startTime = System.currentTimeMillis();
        // 执行方法  proceed就是返回值
        Object proceed = point.proceed();
        // 结束时间
        long endTime = System.currentTimeMillis();
        // 获取入参
        String args = JSON.toJSONString(point.getArgs()[0]);
        // 获取注解中apiType的值
        String apiType = logAnnotation.apiType();
        System.out.println("类名:" + className + ";方法名:" + methodName + ";开始时间:" + startTime + ";结束时间:" + endTime);
        System.out.println("入参:" + args + ";返回值:" + proceed + ";注解参数apiType:"+ apiType);
        // 获取签名
        Signature signature = point.getSignature();
        if(signature instanceof MethodSignature){
            MethodSignature methodSignature = (MethodSignature) signature;
            // 参数名称
            String[] properties = methodSignature.getParameterNames();
            System.out.println("参数名称:" + Arrays.toString(properties));
            // 返回类型
            Class<?> methodReturnType = methodSignature.getReturnType();
            System.out.println("返回类型:" + methodReturnType);
        }
        return proceed;
    }

}

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class TestAnnotation {

    @Autowired
    ServiceImpl service;

    @Test
    public void test(){
        service.jieshao("zhangsan",19);
    }
}

class Student{
    public Student(String name, Integer age){
        this.name = name;
        this.age = age;
    }
    String name;
    Integer age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

@Service
class ServiceImpl{
    @LogAnnotation(reqType = "请求类型", apiType = "api类型")
    public Student jieshao(String name, Integer age){
        Student student = new Student(name, age);
        return  student;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/568403.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ROS/ROS2工程中的路径管理

1 Launch文件访问yaml ROS2中&#xff0c;launch文件可以用python编写&#xff0c;且后缀名为.launch.py&#xff0c;由于python比传统的xml更加灵活&#xff0c;因此&#xff0c;可以在launch文件中找到某个package的yaml。yaml通常存在package下面的config目录下&#xff0c…

30 KVM管理系统资源-CPU热插

文章目录 30 KVM管理系统资源-CPU热插30.1 概述30.2 约束限制30.3 操作步骤30.3.1 配置虚拟机XML30.3.2 热插并上线CPU 30 KVM管理系统资源-CPU热插 30.1 概述 在线增加&#xff08;热插&#xff09;虚拟机CPU是指在虚拟机处于运行状态下&#xff0c;为虚拟机热插CPU而不影响…

企业级信息系统开发——初探Spring - 采用Java配置类管理Bean

文章目录 一、打开项目二、创建子包三、创建杀龙任务类四、创建勇敢骑士类五、创建Spring配置类六、创建测试类七、运行测试类八、总结Spring管理Bean的四种方式 一、打开项目 Maven项目 - SpringDemo 二、创建子包 在net.shuai.spring包里创建day04子包 三、创建杀龙任务…

open3d-gui 所有不同种类的部件

整体效果如上. 下面一步一步添加部件来实现. 目录 1. 菜单栏 2. 文件选择部件 3. 垂直可折叠部件 3.1 label部件 3.2 复选框checkbox 3.3 色板 3.4 下拉框combobox 3.5 拨动开关toggleSwitch 3.6 部件代理WidgetProxy 3.7 WidgetStack 3.8 列表 3.9 树形视图 3.…

AI时代的数据革命,分布式融合存储为何堪当大任?

有人说&#xff0c;以ChatGPT为代表的人工智能应用的兴起标志着AI时代奇点来临。 诚然如斯。这一波AIGC浪潮来袭&#xff0c;让人们真正意识到AI给生产力带来的巨大飞跃。从今年起&#xff0c;AI大模型成为行业用户重点关注的对象&#xff0c;甚至金融、媒体、广告营销等用户纷…

LangChain 实践之工具使用

参考&#xff1a;LangChain中文入门教程 LangChain官网 通过 Google 搜索并返回答案 import os os.environ["OPENAI_API_KEY"] "xxx" os.environ[SERPAPI_API_KEY] "xxx"from langchain.agents import load_tools from langchain.agents im…

华为OD机试真题 Java 实现【优秀学员统计】【2023Q1 100分】

一、题目描述 公司某部门软件教导团正在组织新员工每日打卡学习活动&#xff0c;他们开展这项学习活动已经一个月了&#xff0c;所以想统计下这个月优秀的打卡员工。每个员工会对应一个id&#xff0c;每天的打卡记录记录当天打卡员工的id集合&#xff0c;一共30天。 请你实现…

进入阿里外包一个月,我离职了

有一种打工人的羡慕&#xff0c;叫做“大厂”。 真是年少不知大厂香&#xff0c;错把青春插稻秧。 但是&#xff0c;在深圳有一群比大厂员工更庞大的群体&#xff0c;他们顶着大厂的“名”&#xff0c;做着大厂的工作&#xff0c;还可以享受大厂的伙食&#xff0c;却没有大厂…

设计模式详解之工厂模式

作者&#xff1a;刘文慧 本文将着眼于工厂模式&#xff0c;从简单工厂模式、工厂方法模式和抽象工厂模式出发&#xff0c;展开学习和深入探讨。 ​ 一、概述 我们在进行软件开发时要想实现可维护、可扩展&#xff0c;就需要尽量复用代码&#xff0c;并且降低代码的耦合度&…

SwiftUI 实现一个 iOS 上 Files App 兼容的文件资源管理器

功能需求 在 SwiftUI 中自己白手起家写一个 iOS&#xff08;或iPadOS&#xff09;上迷你的文件资源管理器是有些难度滴&#xff0c;不过从 iOS 11 &#xff08;2017年&#xff09; 官方引入自家的 Files App 之后&#xff0c;我们就可以借助它的魔力轻松完成这一个功能了。 …

防抖和节流 含义及区别图文详解秒懂

防抖和节流都是为解决短时间内频繁触发某个功能函数而导致的性能问题。比如&#xff0c;触发频率过高而导致响应速度跟不上&#xff0c;以致出现延迟&#xff0c;假死或卡顿的现象。 防抖 图解&#xff1a;一件事情&#xff0c;计划5s以后触发&#xff0c;结果中途意外触发了…

一款可以自动写代码的编辑器,解放你的双手

Cursor 是集成了 GPT-4 的 IDE 工具&#xff0c;目前免费并且无需 API Key&#xff0c;支持 Win、Mac、Linux 平台&#xff0c;可以按要求生成代码&#xff0c;或者让 AI 帮助优化代码&#xff0c;分析代码。Cursor目前已经集成了openai的GPT-4&#xff0c;它或将彻底改变我们写…

gdb调试 与 coredump

gdb调试 与 coredump调试 1. 启动gdb2.gdb中的相关命令3. coredump调试&#xff08;附属于gdb调试中一种&#xff0c;当程序出现错误时&#xff0c;会使用coredump调试&#xff09;1&#xff09;coredump是什么&#xff1f;2&#xff09;前期设置3&#xff09;什么情况下会导致…

JavaEE进阶5/25

1.五大类注解详解&#xff08;重点 1.Controller 控制器&#xff0c;用于业务逻辑层&#xff0c;来控制用户的行为。它用来检查用户参数的有效性。 当用户的参数有效的话会继续分发到服务层。controller可以理解为程序的安保系统 2.Service 服务层。归属服务层&#xff0c;调用…

MySQL---SQL优化上(explain分析执行计划、查看SQL的执行效率、定位低效率SQL)

1. 查看SQL的执行效率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以查看服务器状态信息。通 过查看状态信息可以查看对当前数据库的主要操作类型。 --下面的命令显示了当前 session 中所有统计参数的值 show session status like Com____…

【滴水逆向P77】加载进程(PE查看器)应用程序源码解析

在上一篇文章中讲解了通用控件&#xff0c;做了一个基本的加载进程&#xff08;PE查看器&#xff09;的应用程序项目&#xff0c;Win32通用控件&#xff0c;加载进程&#xff08;PE查看器&#xff09;项目初步&#xff0c;大家如果有不懂的可以去看看&#xff0c;由于不是很了解…

如何搭建一个高效、可靠的积分商城系统?

互联网购物的普及&#xff0c;积分商城系统已经成为商家和消费者之间互动的一种常见方式。它不仅可以帮助商家增加品牌影响力&#xff0c;还可以提高顾客体验&#xff0c;从而增加销售额。下面就如何搭建一个高效、可靠的积分商城系统作一些简单介绍。 第一步&#xff1a;确定需…

MyBatis源码学习三之查询主逻辑

MyBatis源码学习三之查询主逻辑 继续上一章节。 MyBatis的一个主要流程图。从图中可以看出&#xff0c;核心的东西主要集中在3个Handler中。分别是入参处理&#xff0c;执行sql语句处理&#xff0c;以及返回结果处理。 一 实例 Test public static void main(String[] args…

Revit建模|10种方法帮你解决Revit操作卡顿!

大家好&#xff0c;这里是建模助手。 相信各位BIMer在使用Revit建模时&#xff0c;肯定遇到过软件加载慢或者程序未响应的现象。我们经过测试发现&#xff0c;除了硬件配置及软件本身的问题以外&#xff0c;建模习惯及软件使用方法不当也会造成软件卡顿。 以下就是我们总结的…

TPlinker解读

参考&#xff1a; 关系抽取之TPLinker解读加源码分析 TPLinker 实体关系抽取代码解读 实体关系联合抽取&#xff1a;TPlinker TPLinker中文注释版 Tagging TPLinker模型需要对关系三元组(subject, relation, object)进行手动Tagging&#xff0c;过程分为三部分&#xff1a; &…