From cad250f02a66237258d1e96addd4704a1fdefb2f Mon Sep 17 00:00:00 2001
From: _老马_ <mayuanfei@163.com>
Date: 星期三, 17 一月 2024 13:47:44 +0800
Subject: [PATCH] !479 update 优化 使用预扫描实体类提升代码性能 * 优化了数据库字段加解密的缓存机制.在自动配置类启动时,就把有加密注解的类进行缓存,以提高速度.
---
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java | 4 +
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java | 4 +
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/core/EncryptorManager.java | 36 +++++------
ruoyi-common/ruoyi-common-encrypt/pom.xml | 11 +++
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java | 76 ++++++++++++++++++++++++
5 files changed, 110 insertions(+), 21 deletions(-)
diff --git a/ruoyi-common/ruoyi-common-encrypt/pom.xml b/ruoyi-common/ruoyi-common-encrypt/pom.xml
index df3222b..baa5931 100644
--- a/ruoyi-common/ruoyi-common-encrypt/pom.xml
+++ b/ruoyi-common/ruoyi-common-encrypt/pom.xml
@@ -42,6 +42,17 @@
<artifactId>spring-webmvc</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.baomidou</groupId>
+ <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.mybatis</groupId>
+ <artifactId>mybatis-spring</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
</dependencies>
</project>
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java
index e988a3a..a0e86a6 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/config/EncryptorAutoConfiguration.java
@@ -1,5 +1,11 @@
package org.dromara.common.encrypt.config;
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.io.Resources;
+import org.dromara.common.encrypt.annotation.EncryptField;
import org.dromara.common.encrypt.core.EncryptorManager;
import org.dromara.common.encrypt.interceptor.MybatisDecryptInterceptor;
import org.dromara.common.encrypt.interceptor.MybatisEncryptInterceptor;
@@ -8,7 +14,20 @@
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
+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.*;
+import java.util.stream.Collectors;
+
+import static org.springframework.util.StringUtils.tokenizeToStringArray;
/**
* 鍔犺В瀵嗛厤缃�
@@ -16,17 +35,66 @@
* @author 鑰侀┈
* @version 4.6.0
*/
-@AutoConfiguration
+@AutoConfiguration(after = MybatisPlusAutoConfiguration.class)
@EnableConfigurationProperties(EncryptorProperties.class)
@ConditionalOnProperty(value = "mybatis-encryptor.enable", havingValue = "true")
+@Slf4j
public class EncryptorAutoConfiguration {
@Autowired
private EncryptorProperties properties;
+ @Autowired
+ private MybatisPlusProperties mybatisPlusProperties;
@Bean
public EncryptorManager encryptorManager() {
- return new EncryptorManager();
+ Map<Class<?>, Set<Field>> fieldCache = scanEncryptClasses(mybatisPlusProperties.getTypeAliasesPackage());
+ return new EncryptorManager(fieldCache);
+ }
+
+ // 閫氳繃typeAliasesPackage璁剧疆鐨勬壂鎻忓寘,鏉ョ‘瀹氬摢浜涘疄浣撶被杩涜缂撳瓨
+ private Map<Class<?>, Set<Field>> scanEncryptClasses(String typeAliasesPackage) {
+ Map<Class<?>, Set<Field>> fieldCache = new HashMap<>();
+ try {
+ String[] packagePatternArray = tokenizeToStringArray(typeAliasesPackage,
+ ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
+ for (String packagePattern : packagePatternArray) {
+ Resource[] resources = new PathMatchingResourcePatternResolver().getResources(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ + ClassUtils.convertClassNameToResourcePath(packagePattern) + "/**/*.class");
+ for (Resource resource : resources) {
+ ClassMetadata classMetadata = new CachingMetadataReaderFactory().getMetadataReader(resource).getClassMetadata();
+ Class<?> clazz = Resources.classForName(classMetadata.getClassName());
+ Set<Field> encryptFieldSet = getEncryptFieldSetFromClazz(clazz);
+ if(CollectionUtil.isNotEmpty(encryptFieldSet)) {
+ fieldCache.put(clazz, encryptFieldSet);
+ }
+ }
+ }
+ }catch (Exception e) {
+ log.error("鍒濆鍖栨暟鎹畨鍏ㄧ紦瀛樻椂鍑洪敊:{}", e.getMessage());
+ }
+ return fieldCache;
+ }
+
+ // 鑾峰緱涓�涓被鐨勫姞瀵嗗瓧娈甸泦鍚�
+ 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;
}
@Bean
@@ -38,4 +106,8 @@
public MybatisDecryptInterceptor mybatisDecryptInterceptor(EncryptorManager encryptorManager) {
return new MybatisDecryptInterceptor(encryptorManager, properties);
}
+
}
+
+
+
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 498b4b8..c2b9cae 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,16 +1,14 @@
package org.dromara.common.encrypt.core;
+import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
+import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.encrypt.annotation.EncryptField;
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;
-import java.util.stream.Collectors;
/**
* 鍔犲瘑绠$悊绫�
@@ -19,6 +17,7 @@
* @version 4.6.0
*/
@Slf4j
+@NoArgsConstructor
public class EncryptorManager {
/**
@@ -32,24 +31,23 @@
Map<Class<?>, Set<Field>> fieldCache = new ConcurrentHashMap<>();
/**
+ * 鏋勯�犳柟娉曚紶鍏ョ被鍔犲瘑瀛楁缂撳瓨
+ *
+ * @param fieldCache 绫诲姞瀵嗗瓧娈电紦瀛�
+ */
+ public EncryptorManager(Map<Class<?>, Set<Field>> fieldCache) {
+ this.fieldCache = fieldCache;
+ }
+
+
+ /**
* 鑾峰彇绫诲姞瀵嗗瓧娈电紦瀛�
*/
public Set<Field> getFieldCache(Class<?> sourceClazz) {
- return fieldCache.computeIfAbsent(sourceClazz, clazz -> {
- Set<Field> fieldSet = new HashSet<>();
- 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;
- });
+ if(ObjectUtil.isNotNull(fieldCache)) {
+ return fieldCache.get(sourceClazz);
+ }
+ return null;
}
/**
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java
index 7c2508f..460aa36 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisDecryptInterceptor.java
@@ -73,7 +73,11 @@
list.forEach(this::decryptHandler);
return;
}
+ // 涓嶅湪缂撳瓨涓殑绫�,灏辨槸娌℃湁鍔犲瘑娉ㄨВ鐨勭被(褰撶劧涔熸湁鍙兘鏄痶ypeAliasesPackage鍐欓敊)
Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
+ if(ObjectUtil.isNull(fields)){
+ return;
+ }
try {
for (Field field : fields) {
field.set(sourceObject, this.decryptField(Convert.toStr(field.get(sourceObject)), field));
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java
index 152f7db..bcc2f4c 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/interceptor/MybatisEncryptInterceptor.java
@@ -82,7 +82,11 @@
list.forEach(this::encryptHandler);
return;
}
+ // 涓嶅湪缂撳瓨涓殑绫�,灏辨槸娌℃湁鍔犲瘑娉ㄨВ鐨勭被(褰撶劧涔熸湁鍙兘鏄痶ypeAliasesPackage鍐欓敊)
Set<Field> fields = encryptorManager.getFieldCache(sourceObject.getClass());
+ if(ObjectUtil.isNull(fields)){
+ return;
+ }
try {
for (Field field : fields) {
field.set(sourceObject, this.encryptField(Convert.toStr(field.get(sourceObject)), field));
--
Gitblit v1.9.3