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