From 97c1fc3bbede906e37ebf104136c8f0ab39e0023 Mon Sep 17 00:00:00 2001 From: zhangxin10 Date: Mon, 30 Nov 2015 14:27:26 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=B7=BB=E5=8A=A0=E6=8B=B7=E8=B4=9D=E7=B1=BB?= =?UTF-8?q?=E4=B8=8A=E7=9A=84=E6=B3=A8=E8=A7=A3=E4=BB=A5=E5=8F=8A=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=92=8C=E5=8F=82=E6=95=B0=E6=B3=A8=E8=A7=A3=202.?= =?UTF-8?q?=E4=BF=AE=E6=94=B9jdbc=E6=8F=92=E4=BB=B6=E7=9A=84=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E7=BA=A7=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skywalking-sdk-plugin/jdbc-plugin/pom.xml | 2 +- skywalking-sdk-plugin/spring-plugin/pom.xml | 11 +++ .../spring/TracingEnhanceProcessor.java | 87 +++++++++++++++---- 3 files changed, 83 insertions(+), 17 deletions(-) diff --git a/skywalking-sdk-plugin/jdbc-plugin/pom.xml b/skywalking-sdk-plugin/jdbc-plugin/pom.xml index 90bb0e1f76..fae1a3c546 100644 --- a/skywalking-sdk-plugin/jdbc-plugin/pom.xml +++ b/skywalking-sdk-plugin/jdbc-plugin/pom.xml @@ -33,7 +33,7 @@ mysql mysql-connector-java 5.1.36 - test + compile diff --git a/skywalking-sdk-plugin/spring-plugin/pom.xml b/skywalking-sdk-plugin/spring-plugin/pom.xml index 70ea10c194..34d0fa1339 100644 --- a/skywalking-sdk-plugin/spring-plugin/pom.xml +++ b/skywalking-sdk-plugin/spring-plugin/pom.xml @@ -40,6 +40,12 @@ 3.2.0.RELEASE compile + + org.springframework + spring-web + 3.2.0.RELEASE + compile + org.springframework spring-context @@ -64,5 +70,10 @@ ${project.version} test + + org.springframework + spring-web + 3.2.9.RELEASE + diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingEnhanceProcessor.java b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingEnhanceProcessor.java index 1e16e6a83e..35d7de6dee 100644 --- a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingEnhanceProcessor.java +++ b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingEnhanceProcessor.java @@ -3,6 +3,7 @@ package com.ai.cloud.skywalking.plugin.spring; import com.ai.cloud.skywalking.buriedpoint.LocalBuriedPointSender; import com.ai.cloud.skywalking.model.Identification; import javassist.*; +import javassist.bytecode.*; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -10,12 +11,17 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.ThreadLocalRandom; +import java.util.logging.Level; +import java.util.logging.Logger; public class TracingEnhanceProcessor implements BeanPostProcessor { - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + private Logger logger = Logger.getLogger(TracingEnhanceProcessor.class.getName()); + + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { List methods = new ArrayList(); for (Method method : bean.getClass().getMethods()) { if (method.isAnnotationPresent(Tracing.class)) { @@ -24,9 +30,12 @@ public class TracingEnhanceProcessor implements BeanPostProcessor { } if (methods.size() > 0) { try { - ClassPool mPool = new ClassPool(true); + ClassPool mPool = ClassPool.getDefault(); + mPool.appendClassPath(new ClassClassPath(bean.getClass())); //创建代理类 CtClass mCtc = createProxyClass(bean, mPool); + //拷贝类上注解 + copyClassesAnnotations(bean, mPool, mCtc); //代理类继承所有的被代理的接口 inheritanceAllInterfaces(bean, mPool, mCtc); // @@ -45,9 +54,13 @@ public class TracingEnhanceProcessor implements BeanPostProcessor { result.append(generateException(method)); // 生成方法体 result.append(generateMethodBody(bean, method)); - // TODO 注解 - // TODO 参数注解 - mCtc.addMethod(CtMethod.make(result.toString(), mCtc)); + CtMethod dest = CtMethod.make(result.toString(), mCtc); + + // 拷贝方法上的注解 + CtMethod origin = convertMethod2CtMethod(bean, mPool, method); + copyAllAnnotation(origin.getMethodInfo(), dest.getMethodInfo()); + + mCtc.addMethod(dest); } mCtc.addConstructor(CtNewConstructor.make("public " + mCtc.getSimpleName() + "(" + LocalBuriedPointSender.class .getName() + " buriedPoint, " + bean.getClass().getName() + " realBean){" + @@ -57,23 +70,69 @@ public class TracingEnhanceProcessor implements BeanPostProcessor { Constructor constructor = classes.getConstructor(LocalBuriedPointSender.class, bean.getClass()); return constructor.newInstance(new LocalBuriedPointSender(), bean); } catch (CannotCompileException e) { - e.printStackTrace(); + logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e); } catch (InstantiationException e) { - e.printStackTrace(); + logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e); } catch (IllegalAccessException e) { - e.printStackTrace(); + logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e); } catch (NoSuchMethodException e) { - e.printStackTrace(); + logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e); } catch (InvocationTargetException e) { - e.printStackTrace(); + logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e); } catch (NotFoundException e) { - e.printStackTrace(); + logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e); } } return bean; } + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + return bean; + } + + private CtMethod convertMethod2CtMethod(Object bean, ClassPool mPool, Method method) throws NotFoundException { + int i = 0; + CtClass ctClass = mPool.get(bean.getClass().getName()); + CtClass[] parameterClass = new CtClass[method.getParameterTypes().length]; + for (Class methodClass : method.getParameterTypes()) { + parameterClass[i++] = mPool.get(methodClass.getName()); + } + return ctClass.getDeclaredMethod(method.getName(), parameterClass); + } + + private void copyClassesAnnotations(Object bean, ClassPool mPool, CtClass mCtc) throws NotFoundException { + // 拷贝类上注解 + CtClass originCtClass = mPool.get(bean.getClass().getName()); + AnnotationsAttribute annotations = (AnnotationsAttribute) originCtClass.getClassFile(). + getAttribute(AnnotationsAttribute.visibleTag); + AttributeInfo newAnnotations = annotations.copy(mCtc.getClassFile().getConstPool(), Collections.EMPTY_MAP); + mCtc.getClassFile().addAttribute(newAnnotations); + } + + private void copyAllAnnotation(MethodInfo origin, MethodInfo dest) { + AnnotationsAttribute annotations = (AnnotationsAttribute) origin.getAttribute(AnnotationsAttribute.visibleTag); + ParameterAnnotationsAttribute pannotations = (ParameterAnnotationsAttribute) origin.getAttribute(ParameterAnnotationsAttribute.visibleTag); + ExceptionsAttribute exAt = (ExceptionsAttribute) origin.getAttribute(ExceptionsAttribute.tag); + SignatureAttribute sigAt = (SignatureAttribute) origin.getAttribute(SignatureAttribute.tag); + if (annotations != null) { + AttributeInfo newAnnotations = annotations.copy(dest.getConstPool(), Collections.EMPTY_MAP); + dest.addAttribute(newAnnotations); + } + if (pannotations != null) { + AttributeInfo newAnnotations = pannotations.copy(dest.getConstPool(), Collections.EMPTY_MAP); + dest.addAttribute(newAnnotations); + } + if (sigAt != null) { + AttributeInfo newAnnotations = sigAt.copy(dest.getConstPool(), Collections.EMPTY_MAP); + dest.addAttribute(newAnnotations); + } + if (exAt != null) { + AttributeInfo newAnnotations = exAt.copy(dest.getConstPool(), Collections.EMPTY_MAP); + dest.addAttribute(newAnnotations); + } + } + private String generateMethodBody(Object bean, Method method) { StringBuilder result = new StringBuilder(); result.append("{"); @@ -160,7 +219,7 @@ public class TracingEnhanceProcessor implements BeanPostProcessor { } private CtClass createProxyClass(Object bean, ClassPool mPool) { - return mPool.makeClass(bean.getClass().getSimpleName() + "$EnhanceBySWTracing$" + ThreadLocalRandom.current().nextInt(100)); + return mPool.makeClass(bean.getClass().getName() + "$EnhanceBySWTracing$" + ThreadLocalRandom.current().nextInt(100)); } private void inheritanceAllInterfaces(Object bean, ClassPool mPool, CtClass mCtc) throws NotFoundException { @@ -168,8 +227,4 @@ public class TracingEnhanceProcessor implements BeanPostProcessor { mCtc.addInterface(mPool.get(classes.getClass().getName())); } } - - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } } \ No newline at end of file -- GitLab