自定义注解

简介: 本文介绍Java自定义注解的实现原理与应用,结合Spring AOP和过滤器实现日志、权限控制等功能。通过@Target、@Retention等元注解定义注解,并在Controller中使用,配合拦截器完成登录验证等实际场景,提升代码可读性与复用性。

1.前言自定义注解目前在我使用过的项目中,主要用用作日志丰富,参数处理,其核心还是借助于Spring的AOP进行实现,本文将结合具体代码演示简单的自定义注解实现流程。2.实现2.1 定义User2.2 定义UserDAO2.3 定义UserService2.4 定义Controller此时浏览器访问:http://{domain}/user/1即可出现对应效果2.5 定义自定义注解说明:@interface 不是interface,是注解类  定义注解Documented这个Annotation可以被写入javadoc  @Retention修饰注解,是注解的注解,称为元注解SOURCE,     // 编译器处理完Annotation后不存储在class中   CLASS,       // 编译器把Annotation存储在class中,这是默认值   RUNTIME  // 编译器把Annotation存储在class中,可以由虚拟机读取,反射需要 @Target注解的作用目标@Target(ElementType.TYPE)                                           //接口、类、枚举、注解@Target(ElementType.FIELD)                                         //字段、枚举的常量@Target(ElementType.METHOD)                                   //方法@Target(ElementType.PARAMETER)                              //方法参数@Target(ElementType.CONSTRUCTOR)                        //构造函数@Target(ElementType.LOCAL_VARIABLE)                     //局部变量@Target(ElementType.ANNOTATION_TYPE)                //注解@Target(ElementType.PACKAGE)                                 //包    可以定义多个方法,每个方法在使用时参照下面的Controller使用即可,实际就是类似于@PostMapping这样的注解中使用过的value,method,produces等,如下:2.6 AOP+Controller使用自定义注解3.总结自定义注解其核心是借助于:@Target 和 @Rentention,@Documented组合实现,其实现还是需要依赖于Spring的AOP进行具体体现,除了上面的用作日志拦截,还可以自定义:数据验证注解,权限注解,缓存注解等多种用途,但其实现基本都遵循上述步骤。4.自定义注解+过滤器实现登陆相关4.1 定义自定义注解@Login4.2 过滤器匹配

Java

运行代码复制代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

package com.zhicall.majordomo.core.security.interceptor;


import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.util.Map;


import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.web.method.HandlerMethod;

import org.springframework.web.multipart.MultipartHttpServletRequest;

import org.springframework.web.multipart.MultipartResolver;

import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;


import com.alibaba.fastjson.JSON;

import com.zhicall.care.realtime.util.ResultMessageBuilder;

import com.zhicall.care.realtime.util.ResultMessageBuilder.ResultMessage;

import com.zhicall.care.system.basic.BeanFactory;

import com.zhicall.majordomo.core.common.constant.GlobalCst;

import com.zhicall.majordomo.core.common.enums.YesOrNo;

import com.zhicall.majordomo.core.security.annotation.Login;

import com.zhicall.majordomo.core.security.constant.Cst;

import com.zhicall.majordomo.core.security.util.UserAuthHelper;


public class UserLoginInterceptor extends HandlerInterceptorAdapter {


@SuppressWarnings({ "unchecked", "rawtypes" })

protected RedisTemplate<String, String> redisTemplate = (RedisTemplate) BeanFactory.getInstance().getBean("redisTemplate");


@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

HandlerMethod handlerMethod = (HandlerMethod) handler;

Login login = handlerMethod.getMethodAnnotation(Login.class);

// 方法被 @Login(YesOrNo.No)标记 表示不需要登陆即可访问 否者都要登录

if (login != null && YesOrNo.NO.equals(login.value())) {

return true;

}

// 做鉴权

       ......

}

}

4.3 Controller中具体使用

Java

运行代码复制代码

1

2

3

4

5

6

7

@Login(YesOrNo.NO)

@RequestMapping(value = "/filter", method = RequestMethod.POST)

public @ResponseBody ResultMessageBuilder.ResultMessage filter(String companyId, String code) {

List<TabInfoVo> merchantsInfoDtos = new ArrayList<>();

merchantsInfoDtos = historyTradeService.filter(companyId, code);

return ok("查询成功", merchantsInfoDtos);

}

相关文章
|
存储 数据采集 数据可视化
神策平台
神策平台
|
存储 域名解析 NoSQL
『MongoDB』MongoDB高可用部署架构——分片集群篇(Sharding)
📣读完这篇文章里你能收获到 - 为什么要使用分片 - Mongodb分片集群有哪些特点 - Mongodb分片集群的完整架构 - Mongodb分片集群数据分布方式 - Mongodb分片集群的设计思路 - Mongodb分片集群搭建及扩容 - 这篇文章强烈建议收藏!!!免得下次找不到
5414 2
『MongoDB』MongoDB高可用部署架构——分片集群篇(Sharding)
|
SQL 关系型数据库 MySQL
Mycat【Mycat部署安装(核心配置及目录结构、安装以及管理命令详解)Mycat高级特性(读写分离概述、搭建读写分离、MySQL双主双从原理)】(三)-全面详解(学习总结---从入门到深化)
Mycat【Mycat部署安装(核心配置及目录结构、安装以及管理命令详解)Mycat高级特性(读写分离概述、搭建读写分离、MySQL双主双从原理)】(三)-全面详解(学习总结---从入门到深化)
1416 0
|
6月前
|
人工智能 IDE API
阿里云百炼Coding Plan 显示售罄抢不到怎么办?GLM-5等模型是全参数满血版的吗?
阿里云百炼Coding Plan提供GLM-5、Qwen3.5-Plus等**满血原版模型**(非量化阉割),仅计费方式不同。抢购建议直选Pro版+卡准每日9:30补货。若求稳,推荐直接使用百炼平台——开通即用、新用户赠100万Tokens,模型一致、按量付费更灵活。
|
6月前
|
NoSQL Java 关系型数据库
手撕分布式锁
本文系统介绍了Redis分布式锁的实现方案。首先阐述了分布式锁的基本概念,包括互斥性、可见性、高可用等核心特性。然后详细讲解了基于Redis的两种实现方式:1)使用SETNX命令实现简单锁,并通过Lua脚本解决原子性问题;2)Redission框架提供的可重入锁、锁续期(WatchDog)和MultiLock多节点锁机制。文章重点分析了锁误删、原子性、主从同步等常见问题及解决方案,并提供了完整的Java代码示例。最后对比了不同方案的优缺点,建议生产环境优先使用Redission框架,其完善的锁管理机制能有效
|
11月前
|
canal 关系型数据库 MySQL
数据同步神器-Canal
Canal是阿里巴巴开源的MySQL增量日志解析工具,通过模拟MySQL主从复制机制,实时捕获数据库变更,实现数据同步至Kafka、Elasticsearch等系统,广泛应用于数据同步、监控、备份与迁移场景。
7935 5
|
9月前
|
消息中间件 Java 数据安全/隐私保护
RabbitMQ集群部署
本文介绍RabbitMQ集群部署,包括普通模式与高可用方案。首先通过Docker搭建三节点集群,配置Erlang Cookie和rabbitmq.conf实现节点通信;接着演示队列创建、数据共享及宕机测试,发现普通模式无高可用能力;进而引入镜像模式,通过策略设置实现队列多副本,支持主从切换;最后重点介绍3.8版本后推荐的仲裁队列,其具备自动选举、强一致性等优势,配置更简便,是实现高可用的首选方案。
RabbitMQ集群部署
|
JSON 前端开发 Java
Validated、Valid 、Validator,他们的区别你知道几个
对于任何基本验证,我们将在方法调用中使用 JSR @Valid注释。另一方面,对于任何组验证,包括组序列,我们需要 在我们的方法调用中使用 Spring 的@Validated注释。
Validated、Valid 、Validator,他们的区别你知道几个
|
Java Spring 容器
Spring boot 自定义ThreadPoolTaskExecutor 线程池并进行异步操作
Spring boot 自定义ThreadPoolTaskExecutor 线程池并进行异步操作
1658 3
|
Java Spring
使用Java实现自定义注解的方法与技巧
使用Java实现自定义注解的方法与技巧