文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎样动态修改JavaBean中注解的参数值

2023-06-06 11:04

关注

小编给大家分享一下怎样动态修改JavaBean中注解的参数值,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

我这里有一个需求需要修改Person类中的一个属性上的注解的值进行修改,例如:

public class Person { private int age; @ApiParam(access="lala") private String name; //get set 方法忽略 }

将@ApiParam(access=“lala”) 修改为@ApiParam(access=“fafa”),经过分析是可以实现的,需要用到动态代理进行操作。

具体源码如下所示:

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface ApiParam { String access() default "";}

反射+动态代理代码如下:

public class TestClazz { public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {  Person person = new Person(); Field value = person.getClass().getDeclaredField("name"); value.setAccessible(true); //APIParam 是一个自定义的注解 ApiParam apiParam = (ApiParam) value.getAnnotation(ApiParam.class); java.lang.reflect.InvocationHandler invocationHandler = Proxy.getInvocationHandler(apiParam); Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues"); //通过反射获取memberValues 这个属性是Map类型 存放着所有的属性。  memberValues.setAccessible(true);  Map<String, Object> values = (Map<String, Object>) memberValues.get(invocationHandler);  String val = (String) values.get("access"); System.out.println("------改之前:"+val); values.put("access", "fafa");//修改属性 System.out.println("-----------------"); //Field value1 = person.getClass().getDeclaredField("name"); value.setAccessible(true); ApiParam apiParam1 = (ApiParam) value.getAnnotation(ApiParam.class); System.out.println("------改之后:"+apiParam1.access()); //动态代理的方式不会改变原先class文件的内容 }}

补充:Java自定义注解并实现注解的伪动态参数传递

自定义注解,实现记录接口的调用日志,此注解可以实现传递伪动态参数。

一、需要引入的jar包:

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency><!-- test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency><!-- json --> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.0</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> </dependency> </dependencies>

二、自定义注解:

package com.example.demo.annotation; import java.lang.annotation.*; @Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ApiOperationLog { String resourceId() default ""; String operationType(); String description() default "";}

三、定义切面:

package com.example.demo.aspect; import com.example.demo.annotation.ApiOperationLog;import net.sf.json.JSONObject;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.stereotype.Component; import java.util.HashMap;import java.util.Map; @Aspect@Componentpublic class ApiOperationAspect {  @Pointcut("@annotation ( com.example.demo.annotation.ApiOperationLog)") public void apiLog() { }  @AfterReturning(pointcut = "apiLog()") public void recordLog(JoinPoint joinPoint) {  MethodSignature signature = (MethodSignature) joinPoint.getSignature();  // 获取方法上的指定注解  ApiOperationLog annotation = signature.getMethod().getAnnotation(ApiOperationLog.class);  // 获取注解中的参数  String resourceId = getAnnotationValue(joinPoint, annotation.resourceId());  String operationType = getAnnotationValue(joinPoint, annotation.operationType());  String description = getAnnotationValue(joinPoint, annotation.description());  System.out.println("resourceId:" + resourceId);  System.out.println("operationType:" + operationType);  System.out.println("description:" + description);  // 将注解中测参数值保存到数据库,实现记录接口调用日志的功能(以下内容省略...)  }   public String getAnnotationValue(JoinPoint joinPoint, String name) {  String paramName = name;  // 获取方法中所有的参数  Map<String, Object> params = getParams(joinPoint);  // 参数是否是动态的:#{paramName}  if (paramName.matches("^#\\{\\D*\\}")) {   // 获取参数名   paramName = paramName.replace("#{", "").replace("}", "");   // 是否是复杂的参数类型:对象.参数名   if (paramName.contains(".")) {    String[] split = paramName.split("\\.");    // 获取方法中对象的内容    Object object = getValue(params, split[0]);    // 转换为JsonObject    JSONObject jsonObject = JSONObject.fromObject(object);    // 获取值    Object o = jsonObject.get(split[1]);    return String.valueOf(o);   }   // 简单的动态参数直接返回   return String.valueOf(getValue(params, paramName));  }  // 非动态参数直接返回  return name; }   public Object getValue(Map<String, Object> map, String paramName) {  for (Map.Entry<String, Object> entry : map.entrySet()) {   if (entry.getKey().equals(paramName)) {    return entry.getValue();   }  }  return null; }   public Map<String, Object> getParams(JoinPoint joinPoint) {  Map<String, Object> params = new HashMap<>(8);  Object[] args = joinPoint.getArgs();  MethodSignature signature = (MethodSignature) joinPoint.getSignature();  String[] names = signature.getParameterNames();  for (int i = 0; i < args.length; i++) {   params.put(names[i], args[i]);  }  return params; } }

四:测试前的准备内容:

// 实体类package com.example.demo.model; public class User {  private Long id; private String name; private int age;  public Long getId() {  return id; }  public void setId(Long id) {  this.id = id; }  public String getName() {  return name; }  public void setName(String name) {  this.name = name; }  public int getAge() {  return age; }  public void setAge(int age) {  this.age = age; }  @Override public String toString() {  return "User{" +    "id=" + id +    ", name='" + name + '\'' +    ", age=" + age +    '}'; }}  // controller层内容package com.example.demo.controller; import com.example.demo.annotation.ApiOperationLog;import com.example.demo.model.User;import org.springframework.web.bind.annotation.RestController; @RestControllerpublic class LoginController {  @ApiOperationLog(resourceId = "#{user.id}",operationType = "SAVE",description = "测试注解传递复杂动态参数") public void saveUser(User user,String id){  System.out.println("测试注解..."); }  @ApiOperationLog(resourceId = "#{id}",operationType = "UPDATE",description = "测试注解传递简单动态参数") public void updateUser(User user,String id){  System.out.println("测试注解..."); } }

五、测试类:

package com.example.demo.aspect; import com.example.demo.DemoApplication;import com.example.demo.controller.LoginController;import com.example.demo.model.User;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = DemoApplication.class)public class ControllerTest {  @Autowired private LoginController loginController;  @Test public void test(){  User user = new User();  user.setId(1L);  user.setName("test");  user.setAge(20);  loginController.saveUser(user,"123");  loginController.updateUser(user,"666"); }}

测试结果:

测试注解...resourceId:1operationType:SAVEdescription:测试注解传递复杂动态参数测试注解...resourceId:666operationType:UPDATEdescription:测试注解传递简单动态参数

以上是“怎样动态修改JavaBean中注解的参数值”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯