From f1208474f771a1c233d7425c8ed13fbaa0d521ac Mon Sep 17 00:00:00 2001
From: baoshiwei <baoshiwei@shlanbao.cn>
Date: 星期三, 12 三月 2025 09:35:13 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/5.X' into 5.X

---
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java |   97 ++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java
index 07c5675..b5f194d 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java
@@ -1,11 +1,24 @@
 package org.dromara.common.encrypt.core;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ReflectUtil;
-import org.dromara.common.encrypt.annotation.EncryptField;
+import lombok.NoArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.io.Resources;
+import org.dromara.common.core.utils.ObjectUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.encrypt.annotation.EncryptField;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.core.type.ClassMetadata;
+import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
+import org.springframework.util.ClassUtils;
 
 import java.lang.reflect.Field;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -18,12 +31,13 @@
  * @version 4.6.0
  */
 @Slf4j
+@NoArgsConstructor
 public class EncryptorManager {
 
     /**
      * 缂撳瓨鍔犲瘑鍣�
      */
-    Map<EncryptContext, IEncryptor> encryptorMap = new ConcurrentHashMap<>();
+    Map<Integer, IEncryptor> encryptorMap = new ConcurrentHashMap<>();
 
     /**
      * 绫诲姞瀵嗗瓧娈电紦瀛�
@@ -31,19 +45,20 @@
     Map<Class<?>, Set<Field>> fieldCache = new ConcurrentHashMap<>();
 
     /**
+     * 鏋勯�犳柟娉曚紶鍏ョ被鍔犲瘑瀛楁缂撳瓨
+     *
+     * @param typeAliasesPackage 瀹炰綋绫诲寘
+     */
+    public EncryptorManager(String typeAliasesPackage) {
+        scanEncryptClasses(typeAliasesPackage);
+    }
+
+
+    /**
      * 鑾峰彇绫诲姞瀵嗗瓧娈电紦瀛�
      */
     public Set<Field> getFieldCache(Class<?> sourceClazz) {
-        return fieldCache.computeIfAbsent(sourceClazz, clazz -> {
-            Field[] declaredFields = clazz.getDeclaredFields();
-            Set<Field> fieldSet = Arrays.stream(declaredFields).filter(field ->
-                    field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class)
-                .collect(Collectors.toSet());
-            for (Field field : fieldSet) {
-                field.setAccessible(true);
-            }
-            return fieldSet;
-        });
+        return ObjectUtils.notNullGetter(fieldCache, f -> f.get(sourceClazz));
     }
 
     /**
@@ -52,11 +67,12 @@
      * @param encryptContext 鍔犲瘑鎵ц鑰呴渶瑕佺殑鐩稿叧閰嶇疆鍙傛暟
      */
     public IEncryptor registAndGetEncryptor(EncryptContext encryptContext) {
-        if (encryptorMap.containsKey(encryptContext)) {
-            return encryptorMap.get(encryptContext);
+        int key = encryptContext.hashCode();
+        if (encryptorMap.containsKey(key)) {
+            return encryptorMap.get(key);
         }
         IEncryptor encryptor = ReflectUtil.newInstance(encryptContext.getAlgorithm().getClazz(), encryptContext);
-        encryptorMap.put(encryptContext, encryptor);
+        encryptorMap.put(key, encryptor);
         return encryptor;
     }
 
@@ -66,7 +82,7 @@
      * @param encryptContext 鍔犲瘑鎵ц鑰呴渶瑕佺殑鐩稿叧閰嶇疆鍙傛暟
      */
     public void removeEncryptor(EncryptContext encryptContext) {
-        this.encryptorMap.remove(encryptContext);
+        this.encryptorMap.remove(encryptContext.hashCode());
     }
 
     /**
@@ -91,4 +107,53 @@
         return encryptor.decrypt(value);
     }
 
+    /**
+     * 閫氳繃 typeAliasesPackage 璁剧疆鐨勬壂鎻忓寘 鎵弿缂撳瓨瀹炰綋
+     */
+    private void scanEncryptClasses(String typeAliasesPackage) {
+        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
+        String[] packagePatternArray = StringUtils.splitPreserveAllTokens(typeAliasesPackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
+        String classpath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
+        try {
+            for (String packagePattern : packagePatternArray) {
+                String path = ClassUtils.convertClassNameToResourcePath(packagePattern);
+                Resource[] resources = resolver.getResources(classpath + path + "/*.class");
+                for (Resource resource : resources) {
+                    ClassMetadata classMetadata = factory.getMetadataReader(resource).getClassMetadata();
+                    Class<?> clazz = Resources.classForName(classMetadata.getClassName());
+                    Set<Field> encryptFieldSet = getEncryptFieldSetFromClazz(clazz);
+                    if (CollUtil.isNotEmpty(encryptFieldSet)) {
+                        fieldCache.put(clazz, encryptFieldSet);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("鍒濆鍖栨暟鎹畨鍏ㄧ紦瀛樻椂鍑洪敊:{}", e.getMessage());
+        }
+    }
+
+    /**
+     * 鑾峰緱涓�涓被鐨勫姞瀵嗗瓧娈甸泦鍚�
+     */
+    private Set<Field> getEncryptFieldSetFromClazz(Class<?> clazz) {
+        Set<Field> fieldSet = new HashSet<>();
+        // 鍒ゆ柇clazz濡傛灉鏄帴鍙�,鍐呴儴绫�,鍖垮悕绫诲氨鐩存帴杩斿洖
+        if (clazz.isInterface() || clazz.isMemberClass() || clazz.isAnonymousClass()) {
+            return fieldSet;
+        }
+        while (clazz != null) {
+            Field[] fields = clazz.getDeclaredFields();
+            fieldSet.addAll(Arrays.asList(fields));
+            clazz = clazz.getSuperclass();
+        }
+        fieldSet = fieldSet.stream().filter(field ->
+                field.isAnnotationPresent(EncryptField.class) && field.getType() == String.class)
+            .collect(Collectors.toSet());
+        for (Field field : fieldSet) {
+            field.setAccessible(true);
+        }
+        return fieldSet;
+    }
+
 }

--
Gitblit v1.9.3