【springMvc】自定义注解的使用方式

🎬 艳艳耶✌️:个人主页
🔥 个人专栏 :《Spring与Mybatis集成整合》
⛺️ 生活的理想,为了不断更新自己 !

1.前言
1.1.什么是注解
Annontation是Java5开始引入的新特征,中文名称叫注解。
它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观、更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。
1.2.注解的用处
- 生成文档。这是最常见的,也是java 最早提供的注解。常用的有@param @return 等
- 跟踪代码依赖性,实现替代配置文件功能。比如Dagger 2 依赖注入,未来java 开发,将大量注解配置,具有很大用处;
- 在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
1.3.注解的原理
注解本质是一个继承了Annotation 的特殊接口,其具体实现类是Java 运行时生成的动态代理类。而我们通过反射获取注解时,返回的是Java 运行时生成的动态代理对象$Proxy1。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler 的invoke 方法。该方法会从memberValues 这个Map 中索引出对应的值。而memberValues 的来源是Java 常量池。
2.注解的案列:
2.1 案例一(获取类与方法上的注解值)
定义一个类:
package com.sy.annotation.pi;public enum TranscationModel {Read, Write, ReadWrite //定义三个实例,可以将它看作类}
写三个注解:
package com.sy.annotation;import java.lang.annotation.*;/*** MyAnnotation1注解可以用在类、接口、属性、方法上* 注解运行期也保留* 不可继承*/
@Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation1 {String name();
}
package com.sy.annotation;import java.lang.annotation.*;/*** MyAnnotation2注解可以用在方法上* 注解运行期也保留* 不可继承*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation2 {TranscationModel model() default TranscationModel.ReadWrite;
}
package com.sy.annotation;import java.lang.annotation.*;/*** @author shenyan** MyAnnotation3注解可以用在方法上* 注解运行期也保留* 可继承*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnnotation3 {TranscationModel[] models() default TranscationModel.ReadWrite;
}
创建几个方法使用这些注解
package com.sy.annotation.Demo1;import com.sy.annotation.MyAnnotation1;
import com.sy.annotation.MyAnnotation2;
import com.sy.annotation.MyAnnotation3;
import com.sy.annotation.TranscationModel;/*** @author shenyan** 获取类与方法上的注解值*/
@MyAnnotation1(name = "艳艳耶")
public class Demo1 {@MyAnnotation1(name = "csdn")private Integer age;@MyAnnotation2(model = TranscationModel.Read)public void list() {System.out.println("list");}@MyAnnotation3(models = {TranscationModel.Read, TranscationModel.Write})public void edit() {System.out.println("edit");}
}
最后,进行测试



2.2 案例二(获取类属性上的注解属性值,默认值的赋予)
package com.sy.annotation.Demo2;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author shenyan* /
//@Retention(RetentionPolicy.SOURCE)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TestAnnotation {String value() default "默认value值";String what() default "这里是默认的what属性对应的值";
}
建立类测试:
有些两个值都赋予了,有些只赋予了一个
package com.sy.annotation.Demo2;/*** @author shenyan** 获取类属性上的注解属性值*/
public class Demo2 {@TestAnnotation(value = "这就是value对应的值_msg1", what = "这就是what对应的值_msg1")private static String msg1;@TestAnnotation("这就是value对应的值1")private static String msg2;@TestAnnotation(value = "这就是value对应的值2")private static String msg3;@TestAnnotation(what = "这就是what对应的值")private static String msg4;
}
测试结果:


2.3 案例三(获取参数修饰注解对应的属性值,非空注解)
package com.sy.annotation;import java.lang.annotation.*;/*** @author shenyan** 非空注解:使用在方法的参数上,false表示此参数可以为空,true不能为空*/
@Documented
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface IsNotNull {boolean value() default false;
}
建立方法,进行测试:
package com.sy.annotation.Demo3;import com.sy.annotation.IsNotNull;/*** @author shenyan** 获取参数修饰注解对应的属性值*/
public class Demo3 {public void hello1(@IsNotNull(true) String name) {System.out.println("hello:" + name);}public void hello2(@IsNotNull String name) {System.out.println("hello:" + name);}
}
测试类:
方法1:

方法2:

方法3:

3.AOP结合自定义注解案例
配置相关AOP pom文件
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!--1. 注解式开发 --><!-- 注解驱动 --><context:annotation-config/><!-- 用注解方式注入bean,并指定查找范围:com.javaxl.ssh2及子子孙孙包--><context:component-scan base-package="com.zking"/><!--开启动态代理--><aop:aspectj-autoproxy /></beans>
定义一个标志日志的注解
package com.sy.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author shenyan*/@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {String desc();
}
再创建一个切面类 LogAspect,用于实现日志记录的逻辑。
package com.sy.annotation.aop;import com.sy.annotation.MyLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;/*** @author shenyan*/
@Component
@Aspect
public class MyLogAspect {private static final Logger logger = LoggerFactory.getLogger(MyLogAspect.class);/*** 只要用到了com.javaxl.p2.annotation.springAop.MyLog这个注解的,就是目标类*/@Pointcut("@annotation(com.sy.annotation.MyLog)")private void MyValid() {}@Before("MyValid()")public void before(JoinPoint joinPoint) {MethodSignature signature = (MethodSignature) joinPoint.getSignature();logger.debug("[" + signature.getName() + " : start.....]");System.out.println("[" + signature.getName() + " : start.....]");MyLog myLog = signature.getMethod().getAnnotation(MyLog.class);logger.debug("【目标对象方法被调用时候产生的日志,记录到日志表中】:"+myLog.desc());System.out.println("【目标对象方法被调用时候产生的日志,记录到日志表中】:" + myLog.desc());}}
在方法上运用日志注解
package com.sy.annotation.aop;import com.sy.annotation.MyLog;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** @author shenyan*/
@Controller
public class LogController {@RequestMapping("/myLog")@MyLog(desc = "这是结合spring aop知识,讲解自定义注解应用的一个案例")public void testLogAspect(){System.out.println("这里随便来点啥");}
}
运行结果:

今日分享结束!

相关文章:
【springMvc】自定义注解的使用方式
🎬 艳艳耶✌️:个人主页 🔥 个人专栏 :《Spring与Mybatis集成整合》 ⛺️ 生活的理想,为了不断更新自己 ! 1.前言 1.1.什么是注解 Annontation是Java5开始引入的新特征,中文名称叫注解。 它提供了一种安全…...
求二维子数组的和(剖析)
文章目录 🐒个人主页🏅JavaSE系列专栏📖前言:本篇剖析一下二维子数组求和规则: 🐒个人主页 🏅JavaSE系列专栏 📖前言:本篇剖析一下二维子数组求和 规则: 这…...
无(低)代码开发思路介绍
无代码或者低代码开发的思路,是通过非编程代码,而是基于页面拖拉拽的方式来实现创建web应用的功能。 作为程序员我们知道私有云公有云已经实现了基础设施的web方式管理。DEVOPS把代码发布,管理也实现了web方式管理。那么我们很容易能够想到,只要把拖拉拽出来的项目自动化部…...
代码随想录刷题 Day14
144.二叉树的前序遍历(opens new window) 要注意下创建函数参数传递不是很理解 class Solution { public:void tranversal(TreeNode* s, vector<int> &b) {if (s NULL) {return;}b.push_back(s->val);tranversal(s->left, b);tranversal(s->right, b);}v…...
二分类问题的解决利器:逻辑回归算法详解(一)
文章目录 🍋引言🍋逻辑回归的原理🍋逻辑回归的应用场景🍋逻辑回归的实现 🍋引言 逻辑回归是机器学习领域中一种重要的分类算法,它常用于解决二分类问题。无论是垃圾邮件过滤、疾病诊断还是客户流失预测&…...
docker alpine镜像中遇到 not found
1.问题: docker alpine镜像中遇到 sh: xxx: not found 例如 # monerod //注:此可执行文件已放到/usr/local/bin/ sh: monerod: not found2.原因 由于alpine镜像使用的是musl libc而不是gnu libc,/lib64/ 是不存在的。但他们是兼容的&…...
python的多线程多进程与多协程
python的多线程是假多线程,本质是交叉串行,并不是严格意义上的并行,或者可以这样说,不管怎么来python的多线程在同一时间有且只有一个线程在执行(举个例子,n个人抢一个座位,但是座位就这一个,不…...
一文介绍使用 JIT 认证后实时同步用户更加优雅
首先本次说的 JIT 指的是 Just In Time ,可以理解为及时录入,一般用在什么样的场景呢? 还记的上次我们说过关于第三方组织结构同步的功能实现,主要目的是将第三方源数据同步到内部平台中来,方便做管控和处理 此处的管…...
搞定“项目八怪”,你就是管理高手!
大家好,我是老原。 玛丽.弗列特说:“权力已经逐渐被视为一个群体的组合能力。我们通过有效联系获取力量。” 有效联系也就是指的沟通,这个部分占据我们项目经理工作内容的80%,可见沟通在项目管理中的重要性。 项目经理的沟通包…...
机器视觉-标定篇
3D结构光标定 结构光视觉的优点: 非接触、信息量大、测精度高、抗干扰能力强。 结构光视觉传感器参数的标定包括:摄像机参数标定、结构光平面参数标定。 结构光视觉测量原理图 我们不考虑镜头的畸变,将相机的成像模型简化为小孔成像模型…...
linux离线安装make
一、下载rpm包 https://pkgs.org/search/?qmake 二、拷贝至服务器 三、安装make rpm -ivh make-3.82-24.el7.x86_64.rpm四、查看是否安装成功 make -v...
【深度学习】卷积神经网络(LeNet)【文章重新修改中】
卷积神经网络 LeNet 前言LeNet 模型代码实现MINST代码分块解析1 构建 LeNet 网络结构2 加载数据集3 初始化模型和优化器4 训练模型5 训练完成 完整代码 Fashion-MINST代码分块解析1 构建 LeNet 网络结构2 初始化模型参数3 加载数据集4 定义损失函数和优化器5 训练模型 完整代码…...
win10 Baichuan2-7B-Chat-4bits 上部署 百川2-7B-对话模型-4bits量化版
搞了两天才搞清楚跑通 好难呢,个人电脑 win10 ,6GB显存 个人感觉 生成速度很慢,数学能力不怎么行 没有ChatGLM2-6B 强,逻辑还行, 要求: 我的部署流程 1.下载模型 ,下载所有文件 然后 放到新建的model目录 https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat-4bits/tr…...
2023/9/20总结
maven maven本质是 一个项目管理工具 将项目开发 和 管理过程 抽象成 一个项目对象模型(POM) POM (Project Object Model) 项目对象模型 作用 项目构建 提供标准的自动化 项目构建 方式依赖管理 方便快捷的管理项目依赖的资源…...
【Git】git 分支或指定文件回退到指定版本
目录 一、分支回滚 1. 使用 git reset 命令 2.使用 git revert 命令 3.使用 git checkout 命令 二、某个文件回滚 1.查看哪些文件发生修改 2.然后查看提交记录(最近几次提交) 3.执行提交命令 一、分支回滚 1. 使用 git reset 命令 命令可以将当前分支的 HEAD 指针指向指…...
Java 消息策略的实现 - Kafak 是怎么设计的
这个也是开放讨论题,主要讨论下 Kafka 在消息中是如何进行实现的。 1_cCyPNzf95ygMFUgsrleHtw976506 21.4 KB 总结 这个题目的开发性太强了。 Kafka 可以用的地方非常多,我经历过的项目有 Kafka 用在消息处理策略上的。这个主要是 IoT 项目,…...
c++opencv RotatedRect 旋转矩形角度转换和顶点顺序转换
这里写自定义目录标题 以下代码记录主要是完成轮廓点求解最小外接矩形之后计算该文本行的角度和旋转矩形的左下(bl),左上(tl),右上(tr),右下(br)的坐标点。 RotatedRect rtminAreaRect(contours…...
Flink-CDC 抽取SQLServer问题总结
Flink-CDC 抽取SQLServer问题总结 背景 flink-cdc 抽取数据到kafka 中,使用flink-sql进行开发,相关问题总结flink-cdc 配置SQLServer cdc参数 1.创建CDC 使用的角色, 并授权给其查询待采集数据数据库 -- a.创建角色 create role flink_role;-- b.授权…...
Linux 系统目录结构 终端
系统目录结构 Linux 或 Unix 操作系统中,所有文件和目录呈一个以根节点为始的倒置的树状结构。文件系统的最顶层是根目录,用 / 来表示根目录。在根目录之下的既可以是目录,也可以是文件,而每一个目录中又可以包含子目录文件。如此…...
Layui + Flask | 实现注册、登录功能(案例篇)(08)
此案例内容比较多,建议滑到最后点击阅读原文,阅读体验更佳。后续也会录制案例视频,将在本周内上传到同名的 b 站账号。 已经看了 layui 表单相关的知识,接下来就可以实现注册功能,功能逻辑如下: 项目创建 新建 flask 项目下载 layui 文件,解压之后复制到指定文件编写前…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...
解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...
【QT控件】显示类控件
目录 一、Label 二、LCD Number 三、ProgressBar 四、Calendar Widget QT专栏:QT_uyeonashi的博客-CSDN博客 一、Label QLabel 可以用来显示文本和图片. 核心属性如下 代码示例: 显示不同格式的文本 1) 在界面上创建三个 QLabel 尺寸放大一些. objectName 分别…...
基于Python的气象数据分析及可视化研究
目录 一.🦁前言二.🦁开源代码与组件使用情况说明三.🦁核心功能1. ✅算法设计2. ✅PyEcharts库3. ✅Flask框架4. ✅爬虫5. ✅部署项目 四.🦁演示效果1. 管理员模块1.1 用户管理 2. 用户模块2.1 登录系统2.2 查看实时数据2.3 查看天…...
