激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - 如何動態修改JavaBean中注解的參數值

如何動態修改JavaBean中注解的參數值

2021-08-10 11:03消魂釘 Java教程

這篇文章主要介紹了如何動態修改JavaBean中注解的參數值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

我這里有一個需求需要修改Person類中的一個屬性上的注解的值進行修改,例如:

?
1
2
3
4
5
6
public class Person {
 private int age;
 @ApiParam(access="lala")
 private String name;
 //get set 方法忽略
}

將@ApiParam(access=“lala”) 修改為@ApiParam(access=“fafa”),經過分析是可以實現的,需要用到動態代理進行操作。

具體源碼如下所示:

?
1
2
3
4
5
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiParam {
 String access() default "";
}

反射+動態代理代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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包:

?
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
45
46
47
48
49
<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>

二、自定義注解:

?
1
2
3
4
5
6
7
8
9
10
package com.example.demo.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiOperationLog {
 String resourceId() default "";
 String operationType();
 String description() default "";
}

三、定義切面:

?
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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
@Component
public 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);
  // 將注解中測參數值保存到數據庫,實現記錄接口調用日志的功能(以下內容省略...)
 }
 
 /**
  * 獲取注解中傳遞的動態參數的參數值
  *
  * @param joinPoint
  * @param name
  * @return
  */
 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;
 }
 
 /**
  * 根據參數名返回對應的值
  *
  * @param map
  * @param paramName
  * @return
  */
 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;
 }
 
 /**
  * 獲取方法的參數名和值
  *
  * @param joinPoint
  * @return
  */
 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;
 }
}

四:測試前的準備內容:

?
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// 實體類
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;
@RestController
public 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("測試注解...");
 }
 
}

五、測試類:

?
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
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");
 }
}

測試結果:

?
1
2
3
4
5
6
7
8
測試注解...
resourceId:1
operationType:SAVE
description:測試注解傳遞復雜動態參數
測試注解...
resourceId:666
operationType:UPDATE
description:測試注解傳遞簡單動態參數

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。如有錯誤或未考慮完全的地方,望不吝賜教。

原文鏈接:https://blog.csdn.net/ltllml44/article/details/84305262

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人免费一区二区 | 成年性羞羞视频免费观看无限 | 久草视频手机在线观看 | 一级免费a | 国产在线中文 | 中国杭州少妇xxxx做受 | 高清久久久久 | 男女一边摸一边做羞羞视频免费 | 在线无码 | 在线播放黄色网址 | 午夜爽爽爽男女免费观看hd | 国产一区二区免费 | 看免费毛片 | 美女视频在线观看黄 | 国产三级午夜理伦三级 | 欧美一级做性受免费大片免费 | 亚洲精品久久久久久久久久 | 成人444kkkk在线观看 | 成人永久免费视频 | 久久99国产精品久久99果冻传媒 | 国产精品自在线拍 | 成人在线免费观看视频 | 亚洲国产二区 | 亚洲第五色综合网 | 日日狠狠久久偷偷四色综合免费 | 成人免费淫片视频软件 | 欧美无限资源 | 伦一区二区三区中文字幕v亚洲 | 丰满年轻岳中文字幕一区二区 | 欧美18一19sex性护士农村 | 成人免费观看av | 成人啪啪18免费网站 | 老a影视网站在线观看免费 国产精品久久久久久久久久尿 | 国产精品18久久久久久久久 | 暴力肉体进入hdxxxx古装 | 成人一区二区三区在线 | 伊人网站| 媚药按摩痉挛w中文字幕 | 国产精品久久久久久久午夜片 | 三人弄娇妻高潮3p视频 | 日本欧美在线播放 |