ソースを参照

新增arthas工具类。

tianyunperfect 4 年 前
コミット
d7984df606

+ 67 - 0
springboot-main/src/main/java/com/alvin/arthas/AopTargetUtils.java

@@ -0,0 +1,67 @@
+package com.alvin.arthas;
+
+import org.springframework.aop.framework.AdvisedSupport;
+import org.springframework.aop.framework.AopProxy;
+import org.springframework.aop.support.AopUtils;
+
+import java.lang.reflect.Field;
+
+/**
+ * 用于arthas获取AOP的代理对象。
+ * 示例:
+ * ognl -x 3 '#springContext=@com.alvin.arthas.ApplicationContextProvider@context,#proxyBean=#springContext.getBean("lightEventPublisher"),@com.alvin.arthas.AopTargetUtils@getTarget(#proxyBean).test' -c 20ad9418
+ *
+ * @author tianyunperfect
+ * @date 2020/12/31
+ */
+public class AopTargetUtils {
+
+
+    /**
+     * 获取 目标对象
+     * @param proxy 代理对象
+     * @return
+     * @throws Exception
+     */
+    public static Object getTarget(Object proxy) throws Exception {
+
+        if(!AopUtils.isAopProxy(proxy)) {
+            return proxy; //不是代理对象
+        }
+
+        if(AopUtils.isJdkDynamicProxy(proxy)) {
+            return getJdkDynamicProxyTargetObject(proxy);
+        } else { //cglib
+            return getCglibProxyTargetObject(proxy);
+        }
+
+    }
+
+
+    private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
+        Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
+        h.setAccessible(true);
+        Object dynamicAdvisedInterceptor = h.get(proxy);
+
+        Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
+        advised.setAccessible(true);
+
+        Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
+
+        return target;
+    }
+
+    private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
+        Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
+        h.setAccessible(true);
+        AopProxy aopProxy = (AopProxy) h.get(proxy);
+
+        Field advised = aopProxy.getClass().getDeclaredField("advised");
+        advised.setAccessible(true);
+
+        Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
+
+        return target;
+    }
+
+}

+ 20 - 0
springboot-main/src/main/java/com/alvin/arthas/ApplicationContextProvider.java

@@ -0,0 +1,20 @@
+package com.alvin.arthas;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ApplicationContextProvider implements ApplicationContextAware {
+
+    private static ApplicationContext context;
+
+    public ApplicationContext getApplicationContext() {
+        return context;
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext ctx) {
+        context = ctx;
+    }
+}