liukx 3 lat temu
rodzic
commit
4dee0a7f49
22 zmienionych plików z 465 dodań i 132 usunięć
  1. 70 6
      elab-redis/README.md
  2. 8 6
      elab-redis/pom.xml
  3. 15 25
      elab-redis/src/main/java/com/elab/redis/componts/config/scope/RedisConfigRefreshCallback.java
  4. 9 1
      elab-redis/src/main/java/com/elab/redis/componts/config/scope/RedisConfigRefreshHelper.java
  5. 11 5
      elab-redis/src/main/java/com/elab/redis/componts/config/scope/RefreshConfigScope.java
  6. 1 1
      elab-redis/src/main/java/com/elab/redis/config/props/ConfigRefreshProperties.java
  7. 3 1
      elab-redis/src/test/resources/application.yml
  8. 60 63
      elab-spring/README.md
  9. 45 6
      elab-spring/src/main/java/com/elab/spring/anno/EnableElabSpring.java
  10. 1 1
      elab-spring/src/main/java/com/elab/spring/componts/BeanAnalyse.java
  11. 9 0
      elab-spring/src/main/java/com/elab/spring/componts/containers/ContainerRefresh.java
  12. 1 5
      elab-spring/src/main/java/com/elab/spring/componts/containers/ContainerRefreshRunner.java
  13. 56 0
      elab-spring/src/main/java/com/elab/spring/componts/endpoints/CatEndpoint.java
  14. 53 0
      elab-spring/src/main/java/com/elab/spring/config/ELabSpringClientsRegistrar.java
  15. 5 1
      elab-spring/src/main/java/com/elab/spring/config/SpringMvcConfig.java
  16. 2 2
      elab-spring/src/main/java/com/elab/spring/config/prop/SpringAutoProperties.java
  17. 1 0
      elab-spring/src/main/java/com/elab/spring/config/prop/ThreadProperties.java
  18. 22 4
      elab-spring/src/main/java/com/elab/spring/intercept/RMQCacheConsumerInterceptor.java
  19. 40 2
      elab-spring/src/main/java/com/elab/spring/utils/SpringUtils.java
  20. 17 0
      elab-spring/src/test/java/com/elab/spring/ELabSpringRunner.java
  21. 28 0
      elab-spring/src/test/java/com/elab/spring/config/ELabSpringClientsRegistrarTest.java
  22. 8 3
      elab-test/src/test/java/com/elab/my/github/FileCase.java

+ 70 - 6
elab-redis/README.md

@@ -14,6 +14,13 @@ spring:
       ttl: 30
       # 注解的统一前缀
       prefix-with: user_
+      config-refresh:
+      	enable: true # 是否开启配置中心功能
+      	config-refresh-cacheKey: config-refresh # 配置更新的缓存的key
+      	config--push-cache-key: aaa # 缓存推送的topic的key
+      	default-config: # 预先设置一些默认值,可以通过redis动态修改
+      		A: A
+      		B: B
 ```
 
 ## 使用类
@@ -24,8 +31,8 @@ spring:
 
 关于分布式锁的应用简单使用案例
 ```java
-    @Autowired
-    private CacheTemplate cacheTemplate;
+@Autowired
+private CacheTemplate cacheTemplate;
 /**
  * 同步和异步
  */
@@ -86,8 +93,6 @@ public void testApp() throws Exception {
 @Cacheable(cacheNames="book", condition="#name.length < 32", unless="#result.name.length > 5"")
 ```
 
-
-
 ### CacheEvict
 
  spring cache不仅支持将数据缓存,还支持将缓存数据删除。此过程经常用于从缓存中清除过期或未使用的数据。 
@@ -110,7 +115,7 @@ public void testApp() throws Exception {
 注解字段描述:
 - cacheName : 自定义的缓存名字,如果为空默认方法名+参数名
 - unionKey  : 唯一的key,重复提交的关键线索,会根据填写的参数名称去获取对应的值作为缓存关键key,如果匹配则认为重复提交.
-    
+  
     -[0] : 代表第0个参数
     
     -{text}  : 代表实体对象参数的参数名称
@@ -129,4 +134,63 @@ public String submit(SomeObject text) throws Exception {
 }
 ```
 - [0] 代表第0个参数
-- {text} : 代表对象的属性
+- {text} : 代表对象的属性
+
+# redis配置中心使用介绍
+
+
+
+```yaml
+# 开启配置刷新功能
+spring.redis.elab.config-refresh.enable: true
+```
+
+此时会注册 : `RedisRefreshConfigure` 配置
+
+大概流程图:
+
+![image-20210901172831387](https://gitee.com/liukaixiong/drawing-bed/raw/master/image/image-20210901172831387.png)
+
+#### RefreshConfigScopeRegistry
+
+负责注册scope,并且还持有BeanDefinitionRegistry容器作为后续注册对象
+
+#### RedisConfigRefreshCallback
+
+比较核心的类,里面主要拥有一些比较核心的功能:
+
+- 刷新配置
+- 创建独立的环境配置,这些配置的优先级会非常高,优先从这个配置里面获取
+- 刷新容器,先销毁相关Scope的Bean,然后重新创建
+
+注意的是需要被刷新的Bean一定是拥有了Scope的标记的
+
+```java
+// 在类上加入该注解,代表这个类会随着容器的刷新而重载
+@Scope(CacheConstants.REFRESH_CONFIG_SCOPE_NAME)
+```
+
+通过修改redis的特定的key -> `spring.redis.elab.config-refresh.config--push-cache-key` 发送任意消息便会触发监听的回调
+
+```
+publish test-redis-* xxx
+```
+
+一旦产生回调之后,便会重构相关scope的属性以及相关的bean..
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 8 - 6
elab-redis/pom.xml

@@ -17,11 +17,11 @@
             <artifactId>redisson-spring-boot-starter</artifactId>
             <version>3.8.2</version>
         </dependency>
-<!--        <dependency>-->
-<!--            <groupId>com.posiedon.wh</groupId>-->
-<!--            <artifactId>config-center-redis-spring-boot-autoconfigure</artifactId>-->
-<!--            <version>0.1.0</version>-->
-<!--        </dependency>-->
+        <!--        <dependency>-->
+        <!--            <groupId>com.posiedon.wh</groupId>-->
+        <!--            <artifactId>config-center-redis-spring-boot-autoconfigure</artifactId>-->
+        <!--            <version>0.1.0</version>-->
+        <!--        </dependency>-->
         <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
         <dependency>
             <groupId>javax.validation</groupId>
@@ -40,7 +40,9 @@
 
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-autoconfigure-processor</artifactId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <version>${springboot.version}</version>
+            <optional>true</optional>
         </dependency>
     </dependencies>
 

+ 15 - 25
elab-redis/src/main/java/com/elab/redis/componts/config/scope/RedisConfigRefreshCallback.java

@@ -57,13 +57,13 @@ public class RedisConfigRefreshCallback implements ApplicationContextAware {
     @Autowired
     private ElabRedisProperties redisProperties;
 
-    private static ConfigurableApplicationContext applicationContext;
+    private ConfigurableApplicationContext applicationContext;
 
     private BeanDefinitionRegistry beanDefinitionRegistry;
 
     @Override
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-        RedisConfigRefreshCallback.applicationContext = (ConfigurableApplicationContext)applicationContext;
+        this.applicationContext = (ConfigurableApplicationContext)applicationContext;
     }
 
     public String redisRefreshKey() {
@@ -123,8 +123,12 @@ public class RedisConfigRefreshCallback implements ApplicationContextAware {
         return false;
     }
 
-    //更新environment 属性值
+    /**
+     * 刷新IOC容器中的环境变量
+     */
     private void refreshEnv() {
+
+        // 是否在配置中开启了刷新配置中心的功能
         if (!enableConfigRefresh()) {
             return;
         }
@@ -133,13 +137,19 @@ public class RedisConfigRefreshCallback implements ApplicationContextAware {
 
         //创建sourceProperty
         if (!checkExistRedisSpringProperty()) {
+
             createRedisSpringProperty();
+
         }
         try {
+
             configMap = redisTemplate.opsForHash().entries(redisConfigKey);
+
             logger.debug("加载可刷新缓存中:" + redisConfigKey + "的key的数据,数据长度大小:" + configMap.size());
+
             // 更新单例配置工厂中的值
             RedisConfigRefreshHelper.getInstance().refresh(configMap);
+
         } catch (Exception e) {
             logger.error("load config from redis fail,reason:" + e.getMessage());
         }
@@ -155,9 +165,11 @@ public class RedisConfigRefreshCallback implements ApplicationContextAware {
         // 更新容器中配置对象的值
         ConcurrentHashMap concurrentHashMap = (ConcurrentHashMap)source.getSource();
 
+        // 先清空,然后再加载
         concurrentHashMap.clear();
 
         Set<Object> keys = configMap.keySet();
+
         for (Object key : keys) {
             concurrentHashMap.put(key, configMap.get(key));
         }
@@ -204,26 +216,4 @@ public class RedisConfigRefreshCallback implements ApplicationContextAware {
         }
     }
 
-    //获得redis 中配置key
-    //    private String getRedisPushKey() {
-    //
-    //        // 默认按照 应用名称+环境标识 作为推送key
-    //        String appName = environment.getProperty("spring.application.name");
-    //        String profile = environment.getProperty("spring.profiles.active");
-    //        String key = null;
-    //        if (appName == null || "".equals(appName)) {
-    //            key = "application";
-    //            if (profile != null && !"".equals(profile)) {
-    //                key += profile;
-    //            }
-    //        } else {
-    //            key = appName.toLowerCase();
-    //            if (profile != null && !"".equals(profile)) {
-    //                key += profile.toLowerCase();
-    //            }
-    //        }
-    //
-    //        return key;
-    //    }
-
 }

+ 9 - 1
elab-redis/src/main/java/com/elab/redis/componts/config/scope/RedisConfigRefreshHelper.java

@@ -25,6 +25,14 @@ public class RedisConfigRefreshHelper {
         return INSTANCE;
     }
 
+    /**
+     * 获取配置缓存信息
+     *
+     * @param key
+     * @param clazz
+     * @param <T>
+     * @return
+     */
     public <T> T get(String key, Class<T> clazz) {
         String body = configCache.get(key);
 
@@ -46,7 +54,7 @@ public class RedisConfigRefreshHelper {
      * @param configMap
      */
     protected synchronized void refresh(Map<String, String> configMap) {
-        this.configCache = configMap;
+        configCache = configMap;
     }
 
 }

+ 11 - 5
elab-redis/src/main/java/com/elab/redis/componts/config/scope/RefreshConfigScope.java

@@ -5,17 +5,23 @@ import org.springframework.beans.factory.config.Scope;
 
 import java.util.concurrent.ConcurrentHashMap;
 
+/**
+ * 描述: 这里主要是管理符合
+ *
+ * @author liukx
+ * @date 2021/9/1 14:02
+ */
 public class RefreshConfigScope implements Scope {
 
-    private final ConcurrentHashMap<String,Object> caches=new ConcurrentHashMap<>();
+    private final ConcurrentHashMap<String, Object> caches = new ConcurrentHashMap<>();
 
     @Override
-    public Object get(String s, ObjectFactory<?> objectFactory) {
-        if(caches.containsKey(s)){
-            return caches.get(s);
+    public Object get(String bean, ObjectFactory<?> objectFactory) {
+        if (caches.containsKey(bean)) {
+            return caches.get(bean);
         }
         Object object = objectFactory.getObject();
-        caches.put(s,object);
+        caches.put(bean, object);
         return object;
     }
 

+ 1 - 1
elab-redis/src/main/java/com/elab/redis/config/props/ConfigRefreshProperties.java

@@ -13,7 +13,7 @@ public class ConfigRefreshProperties {
     /**
      * 是否开启配置更新
      */
-    private boolean enable = true;
+    private boolean enable = false;
 
     /**
      * 配置更新的缓存的key

+ 3 - 1
elab-redis/src/test/resources/application.yml

@@ -9,12 +9,14 @@ spring:
       ttl: 30
       prefix-with: user_
       config-refresh:
+        enable: true
+        config--push-cache-key: abcdefg
         default-config:
           username: xiong
           company: elab
+
   application:
     name: test-redis
-
 #debug: true
 
 elab:

+ 60 - 63
elab-spring/README.md

@@ -1,23 +1,26 @@
----
-
----
-
 # Elab-Spring
 
 该项目用来针对一些Spring的拓展做一些统一的封装使得在使用上非常方便
 
 这里只是大概介绍一下功能的使用。
 
-直接使用的话
+### 按需使用
 
 ```java
 // 如果有相应的配置文件参数,需要将配置文件注入到里面来
 @PropertySource(value = {"classpath:database.properties","classpath:autoConfig.properties"},encoding = "UTF-8")
 // 直接导入相关的配置类
 @Import({SpringCommonConfig.class, DataSourceConfigBean.class, JdbcBeanConfig.class, TransactionConfigBean.class})
+```
 
+### 直接使用
+
+```java
+@EnableElabSpring
 ```
 
+其中该注解内有很多方法,可以根据自己的需要进行开启关闭
+
 ------
 
 [TOC]
@@ -26,7 +29,15 @@
 
 ## 功能介绍
 
-### SpringCommonConfig:基本的Spring相关的配置
+
+
+### 配置相关
+
+#### SpringCommonConfig
+
+基本的Spring相关的配置
+
+
 
 封装了**ClientHttpRequestFactory**、**RestTemplate**、**PropertyPlaceholderConfigurer**等类.
 
@@ -39,8 +50,39 @@ httpClient.read.timeOut=120000
 # 读取property配置文件的路径
 spring.resources.path=classpath:*.properties
 ```
-### swagger 新增扫描多个包的情况
+
+
+#### ThreadConfiguration
+
+异步线程的相关配置,涵盖了定时线程、异步队列、并行线程等等
+
+具体的使用方式参考: `ThreadProcessUtils`
+
+#### SwaggerConfigBean
+
+
+
+```
+#是否开启swagger
+swagger.enable=必填
+# controller路径
+swagger2.basePackage=必填
+# api的标题
+swagger2.title=必填
+# 描述
+swagger2.description=必填
+# 团队服务的URL
+swagger2.termsOfServiceUrl=必填
+# 许可证地址
+swagger2.licenseUrl=必填
+# 版本号
+swagger2.version=必填
+```
+
+##### swagger 新增扫描多个包的情况
+
 `swagger2.basePackage` : 用以","号分割
+
 ```yaml
 swagger2: 
   basePackage: com.elab.marketing.brand.service.impl,com.elab.marketing.brand.controllers
@@ -52,39 +94,9 @@ swagger2:
   enable: true
 ```
 
-### DataSourceConfigBean : 数据源配置
-
-```perl
-
-default.driverClassName=
-default.url=
-default.username=
-default.password=
-default.filters=
-default.initialSize=5
-default.minIdle=10
-default.maxActive=50
-```
-
+#### SpringMvcConfig
 
-### JdbcBeanConfig : JDBC封装类配置
-可选配置
-```perl
-# jdbc的sql文件目录
-jdbc.config.path=sql
-
-# dao接口层扫描
-jdbc.config.scan=com.elab.**
-
-```
-
-### TransactionConfigBean : 事务配置
-针对事物相关的类进行配置
-
-> 这里需要注意的是一般 TransactionConfigBean、JdbcBeanConfig 依赖 DataSourceConfigBean 所以使用的时候,需要将这三个类都一次性导入
-
-
-#### SpringMvcConfig : 基本的SpringMVC容器相关的配置
+基本的SpringMVC容器相关的配置
 
 封装了MultipartResolver等相关配置
 
@@ -93,37 +105,22 @@ jdbc.config.scan=com.elab.**
 mvc.multipartResolver.MaxUploadSize=10485760
 ```
 
-### CommonException : 全局异常定义
+#### CommonException
+
+ 全局异常定义
+
 直接注入就拥有全局异常功能
 
 - `BusinessException` : 该异常表示业务中出现的参数不对,以及一些不会记录Log的异常会直接封装成code+msg返回给前端
-- 
-
-### LogResponseBodyAdvice : 日志id作为结果集返回
-直接注入拥有全局返回日志id的功能
 
+#### LogResponseBodyAdvice
 
-### SwaggerConfigBean : api对象配置
+日志id作为结果集返回
 
-```
-#是否开启swagger
-swagger.enable=必填
-# controller路径
-swagger2.basePackage=必填
-# api的标题
-swagger2.title=必填
-# 描述
-swagger2.description=必填
-# 团队服务的URL
-swagger2.termsOfServiceUrl=必填
-# 许可证地址
-swagger2.licenseUrl=必填
-# 版本号
-swagger2.version=必填
-```
+直接注入拥有全局返回日志id的功能
 
 
-### RestTemplateUtils
+#### RestTemplateUtils
 - 新增`IRestFallback`回调接口
     - `DefaultRestFallBack` 默认的回调 : 一旦请求出现异常,则将该次请求数据记录到`mng_http_failure_data`表中
 > 如果业务有特殊处理,可以实现该接口去覆盖DefaultRestFallBack类的实现。
@@ -300,4 +297,4 @@ String c = completableFutureMap.get("C").get();
 logger.info("获取对应的结果:" + a);
 logger.info("获取对应的结果:" + b);
 logger.info("获取对应的结果:" + c);
-```
+```

+ 45 - 6
elab-spring/src/main/java/com/elab/spring/anno/EnableElabSpring.java

@@ -1,10 +1,7 @@
 package com.elab.spring.anno;
 
 import com.elab.log.asepct.LogResponseBodyAdvice;
-import com.elab.spring.config.RmqConfiguration;
-import com.elab.spring.config.SpringMvcConfig;
-import com.elab.spring.config.SwaggerConfigBean;
-import com.elab.spring.config.ThreadConfiguration;
+import com.elab.spring.config.*;
 import com.elab.spring.exception.CommonException;
 import org.springframework.context.annotation.Import;
 
@@ -12,7 +9,7 @@ import java.lang.annotation.*;
 
 /**
  * @Module 注解
- * @Description 开启Spring内部主要功能
+ * @Description 开启Spring内部主要功能, 按需加载
  * @Author liukaixiong
  * @Date 2020/12/4 10:42
  */
@@ -20,7 +17,49 @@ import java.lang.annotation.*;
 @Target(ElementType.TYPE)
 @Documented
 //, SpringCommonConfig.class 有问题
-@Import({RmqConfiguration.class,ThreadConfiguration.class, LogResponseBodyAdvice.class, CommonException.class, SwaggerConfigBean.class, SpringMvcConfig.class})
+@Import({ELabSpringClientsRegistrar.class})
 public @interface EnableElabSpring {
 
+    /**
+     * 是否开启RMQ配置
+     *
+     * @return
+     */
+    boolean enableRocketMQConfig() default false;
+
+    /**
+     * 是否注册线程池配置
+     *
+     * @return
+     */
+    boolean enableThreadConfig() default true;
+
+    /**
+     * 是否开启CatId的返回配置
+     *
+     * @return
+     */
+    boolean enableCatIdConfig() default true;
+
+    /**
+     * 是否开启公共的异常配置
+     *
+     * @return
+     */
+    boolean enableCommonExceptionConfig() default true;
+
+    /**
+     * 是否开启swagger配置
+     *
+     * @return
+     */
+    boolean enableSwaggerConfig() default false;
+
+    /**
+     * 是否开启mvc的默认配置
+     *
+     * @return
+     */
+    boolean enableMVCConfig() default true;
+
 }

+ 1 - 1
elab-spring/src/main/java/com/elab/spring/componts/BeanAnalyse.java

@@ -225,7 +225,7 @@ public class BeanAnalyse implements ApplicationContextAware {
         return null;
     }
 
-    public void printClassLog(Class clazz){
+    public void printClassLog(Class clazz) {
         BeanDependOnModel beanDependOn = this.getBeanDependOn(clazz);
         Set<Class> dependOnClassList = beanDependOn.getDependOnClassList(excludePackages);
         System.out.println("===================================");

+ 9 - 0
elab-spring/src/main/java/com/elab/spring/componts/containers/ContainerRefresh.java

@@ -7,6 +7,9 @@ import org.springframework.boot.ApplicationArguments;
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * 容器刷新回调
+ */
 public class ContainerRefresh {
 
     private Logger logger = LoggerFactory.getLogger(getClass());
@@ -20,6 +23,11 @@ public class ContainerRefresh {
         return INSTACE;
     }
 
+    /**
+     * 注册需要在容器启动完成之后回调的事件
+     *
+     * @param supplier
+     */
     public void register(SupplierVoid supplier) {
         invokeMethodList.add(supplier);
     }
@@ -40,6 +48,7 @@ public class ContainerRefresh {
             method.process(args);
             logger.debug("<<<<<<<<<<" + method + ">>>>>>>>>>");
         });
+
         isRefresh = true;
     }
 

+ 1 - 5
elab-spring/src/main/java/com/elab/spring/componts/containers/ContainerRefreshRunner.java

@@ -19,10 +19,6 @@ public class ContainerRefreshRunner implements ApplicationRunner {
     public void run(ApplicationArguments args) throws Exception {
         logger.info("===============================容器刷新完成,开启回调方法====================================");
         ContainerRefresh.getInstance().refreshMethod(args);
-        logger.info("  ");
-
-        BusinessException adfasdf = new BusinessException("adfasdf");
-        logger.error("error",adfasdf);
-
+        logger.info("===============================容器刷新完成,结束回调方法====================================");
     }
 }

+ 56 - 0
elab-spring/src/main/java/com/elab/spring/componts/endpoints/CatEndpoint.java

@@ -0,0 +1,56 @@
+package com.elab.spring.componts.endpoints;
+
+import com.dianping.cat.message.io.DefaultMessageQueue;
+import com.dianping.cat.message.io.TcpSocketSender;
+import com.dianping.cat.message.spi.MessageTree;
+import com.elab.spring.utils.SpringUtils;
+import org.codehaus.plexus.PlexusContainer;
+import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
+import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
+import org.unidal.initialization.DefaultModuleContext;
+import org.unidal.initialization.ModuleContext;
+import org.unidal.lookup.ContainerLoader;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+
+/**
+ * Cat排查端点暴露
+ *
+ * @author liukaixiong
+ * @Email liukx@elab-plus.com
+ * @date 2021/9/6 - 13:45
+ */
+@Endpoint(id = "cat")
+public class CatEndpoint {
+
+    @ReadOperation
+    public Object analyseLocalQueue() {
+        PlexusContainer container = ContainerLoader.getDefaultContainer();
+        ModuleContext ctx = new DefaultModuleContext(container);
+        TcpSocketSender tcpSocketSender = ctx.lookup(TcpSocketSender.class);
+        DefaultMessageQueue atomicQueue =
+            SpringUtils.getFieldObjectValue(tcpSocketSender.getClass(), "m_atomicQueue", DefaultMessageQueue.class);
+
+        BlockingQueue m_queue = SpringUtils.getFieldObjectValue(atomicQueue.getClass(), "m_queue", BlockingQueue.class);
+
+        List<MessageTree> messageTrees = new ArrayList<>();
+
+        m_queue.drainTo(messageTrees);
+
+        Map<String, Map<String, Object>> resultMap = new HashMap<>();
+
+        return null;
+        //        messageTrees.forEach((tree) -> {
+        //            String type = tree.getMessage().getType();
+        //            String name = tree.getMessage().getName();
+        //            String key = type + "-" + name;
+        //            Map<String, Object> map = resultMap.computeIfAbsent(key, k -> new HashMap<>());
+        //
+        //        });
+    }
+
+}

+ 53 - 0
elab-spring/src/main/java/com/elab/spring/config/ELabSpringClientsRegistrar.java

@@ -0,0 +1,53 @@
+package com.elab.spring.config;
+
+import com.elab.log.asepct.LogResponseBodyAdvice;
+import com.elab.spring.anno.EnableElabSpring;
+import com.elab.spring.exception.CommonException;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.type.AnnotationMetadata;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 开启客户端的注册
+ * <p>
+ * 集合@EnableElabSpring使用
+ *
+ * @author liukaixiong
+ * @Email liukx@elab-plus.com
+ * @date 2021/9/1 - 15:22
+ */
+public class ELabSpringClientsRegistrar implements ImportBeanDefinitionRegistrar {
+
+    private Map<String, Class<?>> clazzMap = new HashMap<>();
+
+    public ELabSpringClientsRegistrar() {
+        clazzMap.put("enableRocketMQConfig", RmqConfiguration.class);
+        clazzMap.put("enableThreadConfig", ThreadConfiguration.class);
+        clazzMap.put("enableCatIdConfig", LogResponseBodyAdvice.class);
+        clazzMap.put("enableCommonExceptionConfig", CommonException.class);
+        clazzMap.put("enableSwaggerConfig", SwaggerConfigBean.class);
+        clazzMap.put("enableMVCConfig", SpringMvcConfig.class);
+    }
+
+    @Override
+    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
+        Map<String, Object> defaultAttrs = metadata.getAnnotationAttributes(EnableElabSpring.class.getName(), true);
+        registerClients(defaultAttrs, registry);
+    }
+
+    public void registerClients(Map<String, Object> defaultAttrs, BeanDefinitionRegistry registry) {
+        defaultAttrs.forEach((K, V) -> {
+            boolean enable = (boolean)defaultAttrs.getOrDefault(K, false);
+            if (enable) {
+                Class<?> configurationClazz = clazzMap.get(K);
+                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(configurationClazz);
+                registry.registerBeanDefinition(configurationClazz.getSimpleName(), builder.getBeanDefinition());
+            }
+        });
+    }
+
+}

+ 5 - 1
elab-spring/src/main/java/com/elab/spring/config/SpringMvcConfig.java

@@ -1,8 +1,10 @@
 package com.elab.spring.config;
 
+import com.elab.spring.config.prop.SpringAutoProperties;
 import com.elab.spring.intercept.SQLMonitorEventHandler;
 import com.elab.spring.intercept.SQLMonitorPostCallback;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.env.Environment;
@@ -17,6 +19,7 @@ import org.springframework.web.multipart.commons.CommonsMultipartResolver;
  * @email : liukx@elab-plus.com
  */
 @Configuration
+@EnableConfigurationProperties(SpringAutoProperties.class)
 public class SpringMvcConfig {
 
     /**
@@ -27,7 +30,8 @@ public class SpringMvcConfig {
     @Bean(name = "multipartResolver")
     public MultipartResolver getCommonsMultipartResolver(@Autowired Environment env) {
         CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
-        multipartResolver.setMaxUploadSize(Long.valueOf(env.getProperty("mvc.multipartResolver.MaxUploadSize", "10485760")));
+        multipartResolver
+            .setMaxUploadSize(Long.valueOf(env.getProperty("mvc.multipartResolver.MaxUploadSize", "10485760")));
         multipartResolver.setDefaultEncoding("UTF-8");
         return multipartResolver;
     }

+ 2 - 2
elab-spring/src/main/java/com/elab/spring/config/prop/SpringAutoProperties.java

@@ -1,13 +1,13 @@
 package com.elab.spring.config.prop;
 
 import com.elab.spring.enums.ConfigRefreshEnum;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
 
 /**
  * @author liukaixiong
  * @Email liukx@elab-plus.com
  */
-@ConditionalOnProperty(prefix = "elab.spring")
+@ConfigurationProperties(prefix = "elab.spring")
 public class SpringAutoProperties {
 
     /**

+ 1 - 0
elab-spring/src/main/java/com/elab/spring/config/prop/ThreadProperties.java

@@ -8,6 +8,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
  * @author : liukx
  * @time : 2020/8/14 - 14:19
  */
+@ConfigurationProperties(prefix = "elab.spring.thread")
 public class ThreadProperties {
 
     /**

+ 22 - 4
elab-spring/src/main/java/com/elab/spring/intercept/RMQCacheConsumerInterceptor.java

@@ -12,6 +12,8 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * @Module RMQ拦截器
@@ -45,6 +47,8 @@ public class RMQCacheConsumerInterceptor implements ConsumerInterceptor {
      */
     private Long successValidTime = TimeUnit.MINUTES.toMillis(30);
 
+    private Lock lock = new ReentrantLock();
+
     @Override
     public boolean check(MessageModel messageModel, String groupName) {
         /**
@@ -128,15 +132,29 @@ public class RMQCacheConsumerInterceptor implements ConsumerInterceptor {
         redisTemplate.opsForValue().set(key, MqConstants.MSG_OK, maxWaitTime, TimeUnit.MILLISECONDS);
     }
 
+    public void initKey(String key) {
+        lock.lock();
+        try {
+            Integer currentStatus = (Integer)redisTemplate.opsForValue().get(key);
+            if (currentStatus == null) {
+                redisTemplate.opsForValue().set(key, 1);
+            }
+        } finally {
+            lock.unlock();
+        }
+
+    }
+
     @Override
     public void error(MessageModel messageModel, String groupName, Throwable e) {
         String key = getCacheKey(messageModel, groupName);
-        Integer currentStatus = (Integer) redisTemplate.opsForValue().get(key);
-        if (currentStatus <= 1) {
-            redisTemplate.opsForValue().set(key, 2);
+        Integer currentStatus = (Integer)redisTemplate.opsForValue().get(key);
+
+        if (currentStatus == null) {
+            initKey(key);
         }
+
         RocketMonitorUtils.sendConsumerMonitorData(messageModel, -1, e);
     }
 
-
 }

+ 40 - 2
elab-spring/src/main/java/com/elab/spring/utils/SpringUtils.java

@@ -1,19 +1,25 @@
 package com.elab.spring.utils;
 
+import com.alibaba.fastjson.JSON;
 import org.apache.commons.lang3.ArrayUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.stereotype.Component;
 
+import java.lang.reflect.Field;
 import java.util.Map;
 
 /**
+ * Spring拓展的工具类
  *
+ * @author liukx
  */
 @Component
 public class SpringUtils implements ApplicationContextAware {
-
+    private static Logger logger = LoggerFactory.getLogger(SpringUtils.class);
     private static ApplicationContext applicationContext;
 
     public SpringUtils() {
@@ -29,7 +35,7 @@ public class SpringUtils implements ApplicationContextAware {
     }
 
     public static <T> T getBean(String name) {
-        return (T) applicationContext.getBean(name);
+        return (T)applicationContext.getBean(name);
     }
 
     public static <T> T getBean(Class<T> clazz) {
@@ -60,4 +66,36 @@ public class SpringUtils implements ApplicationContextAware {
         String[] activeProfiles = getActiveProfiles();
         return ArrayUtils.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;
     }
+
+    /**
+     * 获取对象的属性字段的值并转换成json
+     *
+     * @param clazz
+     * @param field
+     * @return
+     */
+    public static <T> T getObjectFieldValue(Class<?> clazz, String field, Class<T> valueClazz) {
+        Object bean = null;
+        try {
+            bean = getBean(clazz);
+        } catch (Exception e) {
+            logger.warn("获取bean失败 : " + e.getMessage());
+            return null;
+        }
+        return getFieldObjectValue(bean, field, valueClazz);
+    }
+
+    public static <T> T getFieldObjectValue(Object bean, String field, Class<T> valueClazz) {
+        try {
+            Field declaredField = bean.getClass().getDeclaredField(field);
+            declaredField.setAccessible(true);
+            return (T)declaredField.get(bean);
+        } catch (NoSuchFieldException e) {
+            logger.warn("找不到对应的字段" + e.getMessage());
+        } catch (Exception e) {
+            logger.warn("获取字段异常:" + e.getMessage());
+        }
+        return null;
+    }
+
 }

+ 17 - 0
elab-spring/src/test/java/com/elab/spring/ELabSpringRunner.java

@@ -0,0 +1,17 @@
+package com.elab.spring;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author liukaixiong
+ * @Email liukx@elab-plus.com
+ * @date 2021/9/1 - 15:50
+ */
+@SpringBootApplication
+public class ELabSpringRunner {
+
+    public static void main(String[] args) throws Exception {
+        SpringApplication.run(ELabSpringRunner.class, args);
+    }
+}

+ 28 - 0
elab-spring/src/test/java/com/elab/spring/config/ELabSpringClientsRegistrarTest.java

@@ -0,0 +1,28 @@
+package com.elab.spring.config;
+
+import com.elab.log.asepct.LogResponseBodyAdvice;
+import com.elab.spring.anno.EnableElabSpring;
+import com.elab.spring.exception.CommonException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@EnableElabSpring()
+public class ELabSpringClientsRegistrarTest {
+
+    @Autowired
+    private ThreadConfiguration threadConfiguration;
+
+    @Autowired
+    private LogResponseBodyAdvice logResponseBodyAdvice;
+
+    @Autowired
+    private CommonException commonException;
+
+    @Test
+    public void testRegisterBeanDefinitions() {
+        System.out.println("====");
+    }
+}

+ 8 - 3
elab-test/src/test/java/com/elab/my/github/FileCase.java

@@ -6,6 +6,12 @@ import java.io.File;
 import java.util.HashSet;
 import java.util.Set;
 
+/**
+ * 描述: 用于递归遍历目录并打印MD日志到控制台
+ *
+ * @author liukx
+ * @date 2021/8/31 14:01
+ */
 public class FileCase {
     Set<String> fileList = new HashSet<>();
 
@@ -28,9 +34,8 @@ public class FileCase {
                 deepFile(file.listFiles(), index + 1);
             } else {
                 if (!isEndWith(file.getName(), "png", "gif", "jpg")) {
-                    System.out.println(
-                        appendIndex("-", 1) + "\t" + "[" + file.getName() + "](" + mdPath(file.getPath(),
-                            "D:\\github\\MyHome", ".") + ")");
+                    System.out.println(appendIndex("-", 1) + "\t" + "[" + file.getName() + "](" + mdPath(file.getPath(),
+                        "D:\\github\\MyHome", ".") + ")");
                 }
             }
         }