如何获取方法上声明的注解

news2025/1/24 1:34:06

   开发过程当中部分场景需要获取到方法或类上的注解,但是经常会有无法渠道注解的情况,这种情况很可能是该注解所在的类是一个代理类,比如被AOP动态代理【注意:通过】。本文以CGLIB为例,说明为什么无法取到方法或类上的注解,还有如何取到注解。

      如果是增强的对象,比如JDK动态代理和CGLIB动态代理。因为CGLIB动态代理生成了一个新的继承了动态

原因是:

1.被增强的类

   

package com.changshin.annotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface WhiteList {
}
package com.changshin.component;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Slf4j
public class WhiteListAspect {

    @Pointcut("@annotation(com.changshin.annotation.WhiteList)")
    public void whiteList(){
        log.info("空实现");
    }

    @Before("whiteList()")
    public void start(){
        log.info("对客户白名单进行校验1");
    }

    @AfterReturning("whiteList()")
    public void end(){
        log.info("对客户白名单进行校验2");
    }

}

package com.changshin.web;

import com.changshin.annotation.WhiteList;
import com.changshin.entity.dto.request.UserInfoRequest;
import com.changshin.entity.dto.response.UserInfoResponse;
import com.changshin.lock.BsnService;
import com.changshin.lock.BusinessLockEnum;
import com.changshin.lock.BusinessLockVO;
import com.changshin.lock.LockService;
import com.changshin.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@RestController
public class UserApi {
    private static final Logger log = LoggerFactory.getLogger(UserApi.class);

    @Autowired
    private UserService userService;

    @Autowired
    private LockService lockService;

    @Autowired
    private BsnService bsnService;

    @Autowired
    private ApplicationContext applicationContext;

    @PostMapping(value = "user/queryUserName")
    public UserInfoResponse queryUserNameById(@RequestBody UserInfoRequest request){
        log.info("查询用户姓名请求参数",request);
        String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext,UserService.class);
        Class<?> userServiceBean = applicationContext.getType(beanNames[0]);
        Method[] method1s = userServiceBean.getMethods();
        for (Method method:method1s) {
            if (method.isAnnotationPresent(WhiteList.class)){
                System.out.println("userServiceBean111");
            }
        }
        Class<?> userServiceBeanTarget = null;
        //获取代理类代理的目标类
        if(!Proxy.isProxyClass(userServiceBean)){
            userServiceBeanTarget = ClassUtils.getUserClass(userServiceBean);
        }
        Method[] method2s = userServiceBeanTarget.getMethods();
        for (Method method:method2s) {
            if (method.isAnnotationPresent(WhiteList.class)){
                System.out.println("userServiceBeanTarget222");
            }
        }
        return null;
    }
}

 发现:

1.userServiceBean是userService进行CGLIB增强后的实例,非userService类型的

2.userServiceBeanTarget是userService类型的实例。

 执行API请求代码,发现打印了userServiceBeanTarget222没有打印userServiceBean111。说明

userServiceBean没有获取到注解信息,userServiceBeanTarget获取到了注解信息。

也就是说增强类方法列表中没有获取到注解信息,增强类的目标类的方法列表中得到了注解信息。

 此时userServiceBean.getMethods()实际上调用的是增强类的getMethods方法。对于CGLIB增强的类,需要先获取获取到增强类的目标类,获取到目标类后就可以通过getMethods方法获取到方法,通过获取方法上的注解方法最终获取到方法上的注解。

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

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

相关文章

读《中国省级移动政务服务报告2023》

报告地址&#xff1a; 中国省级移动政务服务报告2022 https://www.digitalelite.cn/h-nd-7846.html 中国省级移动政务服务报告2023 中国省级移动政务服务报告2023 报告分为 引言、评估方法、概貌、指数、标杆、建言 六个部分。 一些思考 移动政务服务应用针对各省的常驻人口…

vueday02——使用NTableData

1.下载naivueui 2.按需导入&#xff0c;不要全局导入 注意不要导入错误组件或者写错组件名称 import { NDataTable } from naive-ui 3.定义表头和数据&#xff01;&#xff01;&#xff01; n-data-table标签必须要使用数据和数据 少一个都不能正确渲染&#xff01;&#xf…

在 Android 上恢复已删除音乐的 5 种简单方法

人们经常将重要的音乐文件保存在智能手机上&#xff0c;以方便随时随地收听自己喜欢的曲目。但是&#xff0c;如果这些珍贵的音乐文件因软件故障或硬件故障而被意外删除或丢失怎么办&#xff1f;这将是许多音乐爱好者的噩梦&#xff01; 如果您也是这些人中的一员&#xff0c;…

8月PMP出成绩了,意味着什么?

之前胖圆给大家分享过&#xff0c;10月16号PMI官网将发布8.19的PMP考试成绩&#xff0c;这两天已经有学员陆陆续续收到考试通过的邮件&#xff0c;还没有收到成绩通知的学员耐心等待&#xff0c;相信努力备考的学员一定都能够顺利通过~ 还没查询成绩的宝子可以移步胖圆上一篇笔…

C/C++面试常见问题——static关键字的主要用法

首先我们要明确一下C/C的内存区域划分 在C/C中内存主要被划分为四大块&#xff0c;堆&#xff0c;栈&#xff0c;全局/静态存储区&#xff0c;代码区 而全局/静态存储区又被细分为常量区(静态常量区&#xff0c;const关键字修饰)&#xff0c;全局区(全局变量区)和静态变量区(…

LiveGBS流媒体平台GB/T28181常见问题-安全控制HTTP接口鉴权勾选流地址鉴权后401Unauthorized如何播放调用接口

LiveGBS流媒体平台GB/T28181常见问题-安全控制HTTP接口鉴权勾选流地址鉴权后401 Unauthorized如何播放调用接口&#xff1f; 1、安全控制1.1、HTTP接口鉴权1.2、流地址鉴权 2、401 Unauthorized2.1、携带token调用接口2.1.1、获取鉴权token2.1.2、调用其它接口2.1.2.1、携带 Co…

微盟盈利困局难解

又是一年“双11”临近&#xff0c;微盟(2013.HK)、有赞等国内电商SaaS头部企业之间的战斗已经悄然打响。 作为从微信生态里生长出来的第三方服务商&#xff0c;根据微盟此前公布2023年半年报&#xff0c;其营收增长背后仍难掩亏损困局。 「不二研究」据微盟财报发现&#xff…

新产品发布新闻稿推广文案怎么写?纯干货

一篇优质的新闻稿传播速度是非常快的&#xff0c;可以让产品获得大量曝光和展现&#xff0c;提高产品的知名度和口碑&#xff0c;这样的稿件撰写起来是需要掌握一定的技巧的&#xff0c;新产品发布新闻稿推广文案怎么写&#xff1f;伯乐网络传媒十多年文案撰写经验&#xff0c;…

Windows10系统开启SNMP服务

Windows10系统开启SNMP服务 1、打开控制面板&#xff0c;选择卸载程序2、点击启用或关闭Windows功能3、将SNMP协议开启&#xff08;如果有该内容请直接跳至步骤7&#xff0c;如找不到该协议请继续看步骤4&#xff09;4、找不到步骤3中内容原因&#xff1a;Windwos10 1809后更新…

Flow深入浅出系列之更聪明的分享 Kotlin Flows

Flow深入浅出系列之在ViewModels中使用Kotlin FlowsFlow深入浅出系列之更聪明的分享 Kotlin FlowsFlow深入浅出系列之使用Kotlin Flow自动刷新Android数据的策略 Flow深入浅出系列之更聪明的分享 Kotlin Flows 使生命周期对上游流有效&#xff0c;以跳过不必要的工作。这是一…

vue2打包优化-小白也可快速上手的一套

需求&#xff1a;项目过大可以使用打包优化&#xff0c;减少项目体积&#xff0c;加速页面加载&#xff0c;增强用户体验&#xff0c;跟着步骤来即可实现&#xff0c;主要是vue2的打包优化&#xff0c;不是vue3&#xff0c;文章可能有点长&#xff0c;但是很实用哈哈&#xff0…

openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数

文章目录 openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数102.1 背景信息102.2 操作步骤 openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数 102.1 背景信息 当用户连接数达到上限后&#…

单片机入门后该怎么学习进一步提升?

单片机入门后该怎么学习进一步提升&#xff1f; 可以将你目前会的单片机基础先整理一下&#xff0c;你看看运用这些基本的外设或者一些入门知识能做个什么东西&#xff0c;最近很多小伙伴找我&#xff0c;说想要一些单片机资料&#xff0c;然后我根据自己从业十年经验&#xff…

Redis主从复制流程

前言 Redis 支持部署多节点&#xff0c;然后按照 1:n 的方式构建主从集群&#xff0c;即一个主库、n 个从库。主从库之间会自动进行数据同步&#xff0c;但是只有主库同时允许读写&#xff0c;从库只允许读。 搭建主从复制集群的目的&#xff1a; 从库可用于容灾备份从库可以…

Unity3D 基础——使用 Mathf.SmoothDamp 函数制作相机的缓冲跟踪效果

使用 Mathf.SmoothDamp 函数制作相机的缓冲跟踪效果&#xff0c;让物体的移动不是那么僵硬&#xff0c;而是做减速的缓冲效果。将以下的脚本绑定在相机上&#xff0c;然后设定好 target 目标对象&#xff0c;即可看到相机的缓动效果。通过设定 smoothTime 的值&#xff0c;可以…

安达发|AI人工智能APS系统:工业4.0的智能引擎

在工业4.0的背景下&#xff0c;人工智能&#xff08;AI&#xff09;和APS智能排程软件已经成为智能工厂的标准配置。它们通过集成先进的信息技术、通信技术和物联网技术&#xff0c;实现了生产过程的智能化、自动化和数据化&#xff0c;从而提高了生产效率、降低了生产成本、提…

运行.sln 32/64位程序,启动不了,无法显示界面

32/64位启动不了&#xff0c;无法显示界面。后台有进程 》环境变量--轴控下&#xff0c;选择的“串口”选择了虚拟串口(比如&#xff1a;com3&#xff0c;是蓝牙串口)&#xff0c;或者因为当前机台以前虚拟过这个串口&#xff0c;所以存在。串口存在&#xff0c;就会去调用函数…

微信小程序----会议oa项目---首页

目录 什么是Flex弹性布局 图解 代码演示 flex弹性布局的特点 Flex 弹性布局的常见属性 flex-wrap属性 flex-flow属性 轮播图后台数据获取及组件使用 首页布局 什么是Flex弹性布局 Flex 弹性布局&#xff08;Flexbox&#xff09;是一种用于在容器中进行灵活排列和对齐元素的…

Java数据结构——应用DFS算法计算流程图下游节点(1)

问题描述&#xff1a; 前端在绘制流程图的时候&#xff0c;某些情况需要对某个节点之后的流程图进行折叠&#xff0c;因此需要得到某个节点的ID后&#xff0c;计算出这个ID下游之后的所有节点&#xff08;找到的节点&#xff0c;边也就找到了&#xff09; 已知条件&#xff1a…

【vscode编辑器插件】前端 php unity自用插件分享

文章目录 一篇一句前言前端vuegitphpunity后端其他待续完结 一篇一句 “思考是最困难的工作&#xff0c;这也许是为什么很少有人这样做。” - 亨利福特&#xff08;Henry Ford&#xff09; 前言 无论是什么语言&#xff0c;我都会选择使用vscode进行开发&#xff0c;我愿称v…