Spring 代理 Bean 获取不到原始 Bean 对象注解解决方法

作者:心城以北 时间:2022-10-31 17:06:08 

一、问题描述

在接受 mq 消息的时候,需要做一个重试次数限制,如果超过 maxNum 就发邮件告警,不再重试。 所以我需要对 consumer 对象进行代理,然后如果超过异常次数,我直接返回成功,并且发送成功消息,但是我获取 consumer handler 方法的方式是通过 method.getAnnotation(XXClient.class) 方式,那么就会返回 null。

1.问题示例代码

  • 目标类, 我这里就之定义一个 test 方法,里面做一些个简单的打印。

@Component
public class TestBean {

@Anno
   public void test() {
       System.out.println("test .....");
   }
}
  • 代理逻辑逻辑处理, 主要就是做一个 @Around 的方法覆盖,保证在调用目标方法之前,先输出我插入的逻辑。

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

String key() default "100%";
}

@Aspect
@Component
public class AnnoAspect {

@Around("@annotation(anno)")
   public Object anno(ProceedingJoinPoint point, Anno anno) throws Throwable {
       System.out.println("anno invoke!!!!!!");
       return point.proceed();
   }

}
  • 调用点, 通过 AnnotationConfigApplicationContext 获取 bean. 然后通过 getMethods() 获取所有的方法,最后查找 Anno 注解的 Method 对象。

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanStart.class);
   TestBean bean = applicationContext.getBean(TestBean.class);

Class<? extends TestBean> classz = bean.getClass();
   Method[] methods = classz.getMethods();

for (Method m : methods) {
       Anno annotation = m.getAnnotation(Anno.class);

if (annotation != null) {
           System.out.println(" ============= invoke test ===========");
           m.invoke(bean, new Object());
       }
   }

由于 m.getAnnotaion(Anno.class) 无法获取到注解信息,所以执行 test 方法失败, 到此问题还原完毕,我们再来看看如何解决。

二、解决方案

通过 Anno ao = AnnotationUtils.findAnnotation(method, Anno.class); 方法获取即可。

有的代码是这样写的 :

String name = classz.getName();
boolean isSpringProxy = name.indexOf("SpringCGLIB$$") >= 0;
Method[] methods;
if (isSpringProxy) {
   methods = ReflectionUtils.getAllDeclaredMethods(AopUtils.getTargetClass(bean));
} else {
   methods = classz.getMethods();
}

// 省略部分代码
if (isSpringProxy) {
   annotation = AnnotationUtils.findAnnotation(method, MqClient.class);
} else {
   annotation = method.getAnnotation(Anno.class);
}

这里他会做一个判断,如果是代理对象就调用 ReflectionUtils.getAllDeclaredMethods 获取所有的方法, 然后再去拿注解的时候二次判断一下,如果存在代理,那么就通过 AnnotationUtils.findAnnotation 感觉是相当的严谨。

总结:

Spring 提供了非常强大的一站式开发功能,而且还提供了比较优秀的工具方法比如: BeanUtils 、ReflectionUtils 、AnnotationUtils 等,这些都是我们值得掌握的基础工具类。

来源:https://juejin.cn/post/7081635762562662413

标签:Spring,代理,Bean,获取,原始,对象,注解
0
投稿

猜你喜欢

  • Jmeter如何添加循环控制器

    2021-06-26 20:09:52
  • Android 8.0系统中通知栏的适配微技巧

    2022-01-30 17:12:43
  • Android指纹识别功能

    2023-11-04 05:09:18
  • Java多线程与线程池技术分享

    2021-07-25 07:35:11
  • 解决Android popupWindow设置背景透明度无效的问题

    2022-12-05 10:39:42
  • Java Http请求方式之RestTemplate常用方法详解

    2021-06-29 02:32:51
  • 十种JAVA排序算法实例

    2022-11-11 00:19:54
  • Java 8 开发的 Mybatis 注解代码生成工具

    2023-01-02 19:53:44
  • C#关闭指定名字进程的方法

    2021-11-23 23:59:42
  • Java实现发红包功能

    2023-12-09 10:33:03
  • Java Config下的Spring Test几种方式实例详解

    2022-12-17 00:31:36
  • Java中后台线程实例解析

    2022-01-05 06:45:08
  • spring boot集成smart-doc自动生成接口文档详解

    2023-11-28 23:08:02
  • SpringBoot使用过滤器、拦截器和监听器的案例代码(Springboot搭建java项目)

    2022-11-21 06:08:54
  • Android 加载大图及多图避免程序出现OOM(OutOfMemory)异常

    2022-05-06 18:32:06
  • Android三方依赖冲突Gradle中exclude的使用

    2023-05-05 05:09:56
  • java开发工作中对InheritableThreadLocal使用思考

    2023-11-24 21:46:44
  • Android Retrofit文件下载进度显示问题的解决方法

    2021-09-23 20:24:10
  • JVM类加载机制原理及用法解析

    2021-08-17 00:22:29
  • ConcurrentMap.putIfAbsent(key,value)用法实例

    2023-03-14 06:45:43
  • asp之家 软件编程 m.aspxhome.com