浏览代码

为二次开发预留接入产生第三方流水号的接口

dark 4 年之前
父节点
当前提交
3018866c62

+ 16 - 0
src/main/java/cn/iocoder/dashboard/framework/tracer/core/ITrace.java

@@ -0,0 +1,16 @@
+package cn.iocoder.dashboard.framework.tracer.core;
+
+/**
+ * 用于扩展获取traceId的场景,需要装载到Spring bean容器中.
+ *
+ * @author 麻薯
+ */
+public interface ITrace {
+
+    /**
+     * 用于接入三方traceId
+     *
+     * @return traceId
+     */
+    String getTraceId();
+}

+ 42 - 4
src/main/java/cn/iocoder/dashboard/framework/tracer/core/util/TracerUtils.java

@@ -1,6 +1,8 @@
 package cn.iocoder.dashboard.framework.tracer.core.util;
 
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.dashboard.framework.tracer.core.ITrace;
+import cn.iocoder.dashboard.util.bean.SpringUtil;
 import org.apache.skywalking.apm.toolkit.trace.TraceContext;
 
 import java.util.UUID;
@@ -12,26 +14,62 @@ import java.util.UUID;
  */
 public class TracerUtils {
 
+    /**
+     * 私有化构造方法
+     */
+    private TracerUtils() {
+    }
+
     /**
      * 获得链路追踪编号
-     *
+     * <p>
      * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。
-     *
+     * <p>
      * 默认情况下,我们使用 Apache SkyWalking 的 traceId 作为链路追踪编号。当然,可能会存在并未引入 Skywalking 的情况,此时使用 UUID 。
      *
      * @return 链路追踪编号
      */
     public static String getTraceId() {
+        // 通过自定义扩展的tracer产生traceId, 在Spring容器加载完成前会获取不到对应的Bean
+        ITrace tracer = null;
+        try {
+            tracer = getTracer();
+        } catch (Throwable ignore) {
+        }
+        if (null != tracer) {
+            try {
+                return tracer.getTraceId();
+            } catch (Throwable ignored) {
+            }
+        }
         // 通过 SkyWalking 获取链路编号
         try {
             String traceId = TraceContext.traceId();
             if (StrUtil.isNotBlank(traceId)) {
                 return traceId;
             }
-        } catch (Throwable ignore) {}
+        } catch (Throwable ignore) {
+        }
         // TODO 芋艿 多次调用会问题
 
-        // TODO 麻薯 定义一个给外部扩展的接口,默认在未接入Skywalking时,输出UUID
+        return defaultTraceId();
+    }
+
+    /**
+     * 从Spring 容器中获取 ITrace 类,返回可以为null
+     *
+     * @return ITrace
+     */
+    private static ITrace getTracer() {
+        return SpringUtil.getBean(ITrace.class);
+    }
+
+    /**
+     * 默认生成TraceId规则为UUID
+     *
+     * @return UUID
+     */
+    private static String defaultTraceId() {
         return "UUID:" + UUID.randomUUID().toString();
     }
 

+ 83 - 0
src/main/java/cn/iocoder/dashboard/util/bean/SpringUtil.java

@@ -0,0 +1,83 @@
+package cn.iocoder.dashboard.util.bean;
+
+import org.springframework.beans.BeansException;
+
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+
+import org.springframework.context.ApplicationContext;
+
+import org.springframework.context.ApplicationContextAware;
+
+import org.springframework.stereotype.Component;
+
+
+@Component
+public class SpringUtil implements ApplicationContextAware {
+
+    /**
+     * Spring context
+     */
+    private static ApplicationContext applicationContext = null;
+
+    public void setApplicationContext(ApplicationContext context) throws BeansException {
+        if (applicationContext == null) {
+            applicationContext = context;
+        }
+    }
+
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    public static void setAppCtx(ApplicationContext webAppCtx) {
+        if (webAppCtx != null) {
+            applicationContext = webAppCtx;
+        }
+    }
+
+
+    /**
+     * 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象
+     */
+    public static <T> T getBean(Class<T> clazz) {
+        return getApplicationContext() == null ? null : getApplicationContext().getBean(clazz);
+    }
+
+
+    public static <T> T getBean(String name, Class<T> clazz) throws ClassNotFoundException {
+        return getApplicationContext() == null ? null : getApplicationContext() .getBean(name, clazz);
+    }
+
+
+    public static final Object getBean(String beanName) {
+        return getApplicationContext() == null ? null : getApplicationContext() .getBean(beanName);
+    }
+
+
+    public static final Object getBean(String beanName, String className) throws ClassNotFoundException {
+        Class<?> clz = Class.forName(className);
+        return getApplicationContext() == null ? null : getApplicationContext() .getBean(beanName, clz.getClass());
+
+    }
+
+
+    public static boolean containsBean(String name) {
+        return getApplicationContext() == null ? null : getApplicationContext() .containsBean(name);
+    }
+
+
+    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+        return getApplicationContext() == null ? null : getApplicationContext() .isSingleton(name);
+    }
+
+
+    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
+        return getApplicationContext() == null ? null : getApplicationContext() .getType(name);
+    }
+
+
+    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+        return getApplicationContext() == null ? null : getApplicationContext() .getAliases(name);
+    }
+
+}