diff --git a/samples/skywalking-auth/skywalking-auth.iml b/samples/skywalking-auth/skywalking-auth.iml
new file mode 100644
index 000000000..dd834b565
--- /dev/null
+++ b/samples/skywalking-auth/skywalking-auth.iml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/skywalking-sdk-plugin/spring-plugin/pom.xml b/skywalking-sdk-plugin/spring-plugin/pom.xml
index 34d0fa133..7d6a8cafa 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-context
+ 3.2.0.RELEASE
+ compile
+
org.springframework
spring-web
@@ -75,5 +81,10 @@
spring-web
3.2.9.RELEASE
+
+ org.springframework
+ spring-context
+ 3.0.0.RELEASE
+
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingClassBean.java b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingClassBean.java
new file mode 100644
index 000000000..259ea221f
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingClassBean.java
@@ -0,0 +1,31 @@
+package com.ai.cloud.skywalking.plugin.spring;
+
+public class TracingClassBean {
+ private String packageName;
+ private String className;
+ private String method;
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+}
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 35d7de6de..d087861ed 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
@@ -2,164 +2,187 @@ package com.ai.cloud.skywalking.plugin.spring;
import com.ai.cloud.skywalking.buriedpoint.LocalBuriedPointSender;
import com.ai.cloud.skywalking.model.Identification;
+import com.ai.cloud.skywalking.plugin.spring.util.ConcurrentHashSet;
import javassist.*;
-import javassist.bytecode.*;
+import javassist.bytecode.AnnotationsAttribute;
+import javassist.bytecode.ConstPool;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
-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.Set;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
-public class TracingEnhanceProcessor implements BeanPostProcessor {
+public class TracingEnhanceProcessor implements DisposableBean, BeanPostProcessor, BeanFactoryPostProcessor, ApplicationContextAware {
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)) {
- methods.add(method);
- }
- }
- if (methods.size() > 0) {
- try {
- ClassPool mPool = ClassPool.getDefault();
- mPool.appendClassPath(new ClassClassPath(bean.getClass()));
- //创建代理类
- CtClass mCtc = createProxyClass(bean, mPool);
- //拷贝类上注解
- copyClassesAnnotations(bean, mPool, mCtc);
- //代理类继承所有的被代理的接口
- inheritanceAllInterfaces(bean, mPool, mCtc);
- //
- mCtc.setSuperclass(mPool.get(bean.getClass().getName()));
- //添加字段
- mCtc.addField(CtField.make("private " + LocalBuriedPointSender.class.getName() + " buriedPoint;", mCtc));
- mCtc.addField(CtField.make("private " + bean.getClass().getName() + " realBean;", mCtc));
- // 校验方法
- for (Method method : methods) {
- // 生成方法头
- StringBuilder result = new StringBuilder();
- result.append(generateMethodHead(method));
- // 生成方法参数
- result.append(generateMethodParameter(method));
- // 生成抛出异常
- result.append(generateException(method));
- // 生成方法体
- result.append(generateMethodBody(bean, method));
- CtMethod dest = CtMethod.make(result.toString(), mCtc);
+ private final Set beanSet = new ConcurrentHashSet();
+ private ApplicationContext applicationContext;
- // 拷贝方法上的注解
- 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){" +
- "this.buriedPoint = buriedPoint;this.realBean = realBean;}", mCtc));
- mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));
- Class> classes = mCtc.toClass();
- Constructor> constructor = classes.getConstructor(LocalBuriedPointSender.class, bean.getClass());
- return constructor.newInstance(new LocalBuriedPointSender(), bean);
- } catch (CannotCompileException e) {
- logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e);
- } catch (InstantiationException e) {
- logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e);
- } catch (IllegalAccessException e) {
- logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e);
- } catch (NoSuchMethodException e) {
- logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e);
- } catch (InvocationTargetException e) {
- logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e);
- } catch (NotFoundException e) {
- logger.log(Level.ALL, "Failed to create the instance of the class[" + beanName + "]", e);
- }
- }
-
- return bean;
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ applicationContext.getBeansOfType(TracingClassBean.class);
+ //beanSet.addAll(beanFactory.getBeansOfType(TracingClassBean.class).values());
}
+ @Override
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());
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+ boolean isMatch = false;
+ TracingClassBean matchClassBean = null;
+ for (TracingClassBean tracingClassBean : beanSet) {
+ //不符合符合规则
+ //报名只支持精确匹配,类名支持*号模糊
+ if (isPackageMatch(bean.getClass().getPackage().getName(), tracingClassBean.getPackageName())
+ || isClassNameMatch(bean, tracingClassBean.getClassName())) {
+ isMatch = true;
+ matchClassBean = tracingClassBean;
+ continue;
+ }
}
- return ctClass.getDeclaredMethod(method.getName(), parameterClass);
+ if (!isMatch || matchClassBean == null) {
+ return bean;
+ }
+
+ //符合规范
+ try {
+ ClassPool pool = ClassPool.getDefault();
+ CtClass ctSource = pool.get(bean.getClass().getName());
+ CtClass ctDestination = pool.makeClass(generateProxyClassName(bean), ctSource);
+ //拷贝所有的方法,所有的属性以及注解
+ copy(ctSource, ctDestination);
+
+ String methodPrefix = matchClassBean.getMethod();
+ if (matchClassBean.getMethod().indexOf("*") != -1) {
+ methodPrefix = methodPrefix.substring(0, matchClassBean.getMethod().indexOf("*"));
+ }
+
+ List methods = new ArrayList();
+ for (CtMethod method : ctDestination.getDeclaredMethods()) {
+ if (methodPrefix.length() <= 0 || method.getName().startsWith(methodPrefix)) {
+ methods.add(method);
+ }
+ }
+
+ for (CtMethod method : methods) {
+ enhanceMethod(bean, method);
+ }
+
+ // 判断是否存在无参的构造函数,如果没有,则
+ // 生成实例,构造函数
+ Class generateClass = ctDestination.toClass();
+
+ Object newBean = generateClass.newInstance();
+ BeanUtils.copyProperties(bean, newBean);
+ return newBean;
+ } catch (NotFoundException e) {
+ logger.log(Level.ALL, "Class [" + beanName.getClass().getName() + "] cannot be found");
+ throw new IllegalStateException("Class [" + beanName.getClass().getName() + "] cannot be found", e);
+ } catch (CannotCompileException e) {
+ throw new IllegalStateException("Class [" + beanName.getClass().getName() + "] cannot be compile", e);
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return bean;
}
- 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 String generateProxyClassName(Object bean) {
+ return bean.getClass().getName() + "$EnhanceBySWTracing$" + ThreadLocalRandom.current().nextInt(100);
}
- 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 void copy(CtClass ctSource, CtClass ctDestination) {
+ try {
+ // copy fields
+ ConstPool cp = ctDestination.getClassFile().getConstPool();
+ for (CtField f : ctSource.getDeclaredFields()) {
+ CtClass fieldTypeClass = ClassPool.getDefault().get(f.getType().getName());
+ //with annotations
+ AnnotationsAttribute invAnn = (AnnotationsAttribute) f.getFieldInfo().getAttribute(
+ AnnotationsAttribute.invisibleTag);
+ AnnotationsAttribute visAnn = (AnnotationsAttribute) f.getFieldInfo().getAttribute(
+ AnnotationsAttribute.visibleTag);
+ CtField ctField = new CtField(fieldTypeClass, f.getName(), ctDestination);
+ if (invAnn != null) {
+ ctField.getFieldInfo().addAttribute(invAnn.copy(cp, null));
+ }
+ if (visAnn != null) {
+ ctField.getFieldInfo().addAttribute(visAnn.copy(cp, null));
+ }
+
+ ctDestination.addField(ctField);
+ }
+ // copy methods
+ for (CtMethod m : ctSource.getDeclaredMethods()) {
+ //copy the method prefixing it with the source class name
+ CtMethod newm = CtNewMethod.copy(m, /*ctSource.getSimpleName() + "_" + */m.getName(), ctDestination, null);
+ // with annotations
+ AnnotationsAttribute invAnn = (AnnotationsAttribute) m.getMethodInfo().getAttribute(
+ AnnotationsAttribute.invisibleTag);
+ AnnotationsAttribute visAnn = (AnnotationsAttribute) m.getMethodInfo().getAttribute(
+ AnnotationsAttribute.visibleTag);
+ if (invAnn != null) {
+ newm.getMethodInfo().addAttribute(invAnn.copy(cp, null));
+ }
+ if (visAnn != null) {
+ newm.getMethodInfo().addAttribute(visAnn.copy(cp, null));
+ }
+
+ ctDestination.addMethod(newm);
+ }
+
+ // copy annotation
+ AnnotationsAttribute invAnn = (AnnotationsAttribute) ctSource.getClassFile().getAttribute(
+ AnnotationsAttribute.invisibleTag);
+ AnnotationsAttribute visAnn = (AnnotationsAttribute) ctSource.getClassFile().getAttribute(
+ AnnotationsAttribute.visibleTag);
+ if (invAnn != null) {
+ ctDestination.getClassFile().addAttribute(invAnn.copy(cp, null));
+ }
+ if (visAnn != null) {
+ ctDestination.getClassFile().addAttribute(visAnn.copy(cp, null));
+ }
+
+ } catch (Exception e) {
+ logger.log(Level.ALL, "Failed to generate proxy class ");
+ throw new IllegalStateException("Failed to generate proxy class");
}
}
- private String generateMethodBody(Object bean, Method method) {
- StringBuilder result = new StringBuilder();
- result.append("{");
- result.append(" try{ this.buriedPoint.beforeSend");
- result.append(generateBeforeSendParamter(bean, method));
- if (!"void".equals(method.getReturnType().getSimpleName())) {
- result.append(" return ");
- }
- result.append("this.realBean." + method.getName());
- result.append(generateMethodInvokeParameters(method));
- result.append("}catch(Throwable e){");
- result.append(" this.buriedPoint.handleException(e);");
- result.append(" throw e;");
- result.append("}finally{");
- result.append(generateAfterTracing());
- result.append("}}");
- return result.toString();
+ protected void enhanceMethod(Object bean, CtMethod method) throws CannotCompileException, NotFoundException {
+ ClassPool cp = method.getDeclaringClass().getClassPool();
+ method.addLocalVariable("___sender", cp.get(LocalBuriedPointSender.class.getName()));
+ method.insertBefore("___sender = new " + LocalBuriedPointSender.class.getName() + "();___sender.beforeSend"
+ + generateBeforeSendParameter(bean, method));
+ method.addCatch("new " + LocalBuriedPointSender.class.getName() + "().handleException(e);throw e;",
+ ClassPool.getDefault().getCtClass(Throwable.class.getName()), "e");
+ method.insertAfter("new " + LocalBuriedPointSender.class.getName() + "().afterSend();", true);
}
- private String generateBeforeSendParamter(Object bean, Method method) {
+ private String generateBeforeSendParameter(Object bean, CtMethod method) throws NotFoundException {
StringBuilder builder = new StringBuilder("(" + Identification.class.getName() + ".newBuilder().viewPoint(\""
+ bean.getClass().getName() + "." + method.getName());
builder.append("(");
- for (Class> param : method.getParameterTypes()) {
+ for (CtClass param : method.getParameterTypes()) {
builder.append(param.getSimpleName() + ",");
}
- if (method.getGenericParameterTypes().length > 0) {
+ if (method.getParameterTypes().length > 0) {
builder = builder.delete(builder.length() - 1, builder.length());
}
builder.append(")");
@@ -167,64 +190,27 @@ public class TracingEnhanceProcessor implements BeanPostProcessor {
return builder.toString();
}
- private String generateMethodInvokeParameters(Method method) {
- StringBuilder result = new StringBuilder();
- int index;
- result.append("(");
- index = 0;
- for (Class> parameter : method.getParameterTypes()) {
- result.append(parameter.getSimpleName().toLowerCase() + "$" + (index++) + ",");
+
+ private boolean isClassNameMatch(Object bean, String tracingClassBean) {
+ //
+ String classNamePrefix = tracingClassBean;
+ if (tracingClassBean.endsWith("*")) {
+ classNamePrefix = tracingClassBean.substring(0, tracingClassBean.indexOf('*'));
}
- if (method.getParameterTypes().length > 0) {
- result = result.delete(result.length() - 1, result.length());
- }
- result.append(");");
- return result.toString();
+ return bean.getClass().getSimpleName().startsWith(classNamePrefix);
}
- private String generateAfterTracing() {
- return " this.buriedPoint.afterSend();";
+ private boolean isPackageMatch(Object bean, String packageName) {
+ return bean.getClass().getPackage().equals(packageName);
}
- private String generateException(Method method) {
- StringBuilder resultB = new StringBuilder(" throws ");
- for (Class> exceptionClasses : method.getExceptionTypes()) {
- resultB.append(exceptionClasses.getName() + ",");
- }
- if (method.getExceptionTypes().length > 0) {
- resultB.delete(resultB.length() - 1, resultB.length());
- } else {
- resultB = new StringBuilder();
- }
- return resultB.toString();
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = applicationContext;
}
- private String generateMethodParameter(Method method) {
- StringBuilder result = new StringBuilder();
- result.append("(");
- int index = 0;
- for (Class> param : method.getParameterTypes()) {
- result.append(param.getName() + " " + param.getSimpleName().
- toLowerCase() + "$" + (index++) + ",");
- }
- if (method.getGenericParameterTypes().length > 0) {
- result = result.delete(result.length() - 1, result.length());
- }
- result.append(")");
- return result.toString();
- }
+ @Override
+ public void destroy() throws Exception {
- private String generateMethodHead(Method method) {
- return "public " + method.getReturnType().getName() + " " + method.getName();
}
-
- private CtClass createProxyClass(Object bean, ClassPool mPool) {
- return mPool.makeClass(bean.getClass().getName() + "$EnhanceBySWTracing$" + ThreadLocalRandom.current().nextInt(100));
- }
-
- private void inheritanceAllInterfaces(Object bean, ClassPool mPool, CtClass mCtc) throws NotFoundException {
- for (Class> classes : bean.getClass().getInterfaces()) {
- mCtc.addInterface(mPool.get(classes.getClass().getName()));
- }
- }
-}
\ No newline at end of file
+}
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingPackageBean.java b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingPackageBean.java
new file mode 100644
index 000000000..8ebd63d24
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/TracingPackageBean.java
@@ -0,0 +1,13 @@
+package com.ai.cloud.skywalking.plugin.spring;
+
+public class TracingPackageBean {
+ private String packageName;
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+}
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/extansion/SpringExtensionFactory.java b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/extansion/SpringExtensionFactory.java
new file mode 100644
index 000000000..a93725342
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/extansion/SpringExtensionFactory.java
@@ -0,0 +1,4 @@
+package com.ai.cloud.skywalking.plugin.spring.extansion;
+
+public class SpringExtensionFactory {
+}
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingBeanDefinitionParser.java b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingBeanDefinitionParser.java
new file mode 100644
index 000000000..608b4e025
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingBeanDefinitionParser.java
@@ -0,0 +1,21 @@
+package com.ai.cloud.skywalking.plugin.spring.parser;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+public class TracingBeanDefinitionParser implements BeanDefinitionParser {
+
+ @Override
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ RootBeanDefinition beanDefinition = new RootBeanDefinition();
+ String toBeTracingBeanClassName = element.getAttribute("name");
+ String methodPattern = element.getAttribute("method");
+ //校验入参
+
+ //
+ return beanDefinition;
+ }
+}
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingBeanPostProcessorParser.java b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingBeanPostProcessorParser.java
new file mode 100644
index 000000000..a94e4722b
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingBeanPostProcessorParser.java
@@ -0,0 +1,18 @@
+package com.ai.cloud.skywalking.plugin.spring.parser;
+
+import com.ai.cloud.skywalking.plugin.spring.TracingEnhanceProcessor;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+public class TracingBeanPostProcessorParser implements BeanDefinitionParser {
+ @Override
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ RootBeanDefinition beanDefinition = new RootBeanDefinition();
+ //
+ beanDefinition.setBeanClass(TracingEnhanceProcessor.class);
+ return beanDefinition;
+ }
+}
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingPackageDefinitionParser.java b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingPackageDefinitionParser.java
new file mode 100644
index 000000000..74106ad7f
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/parser/TracingPackageDefinitionParser.java
@@ -0,0 +1,13 @@
+package com.ai.cloud.skywalking.plugin.spring.parser;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+public class TracingPackageDefinitionParser implements BeanDefinitionParser {
+ @Override
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ return null;
+ }
+}
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/schema/SWNamespaceHandler.java b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/schema/SWNamespaceHandler.java
new file mode 100644
index 000000000..d6f5c822b
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/java/com/ai/cloud/skywalking/plugin/spring/schema/SWNamespaceHandler.java
@@ -0,0 +1,16 @@
+package com.ai.cloud.skywalking.plugin.spring.schema;
+
+import com.ai.cloud.skywalking.plugin.spring.parser.TracingBeanDefinitionParser;
+import com.ai.cloud.skywalking.plugin.spring.parser.TracingBeanPostProcessorParser;
+import com.ai.cloud.skywalking.plugin.spring.parser.TracingPackageDefinitionParser;
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+public class SWNamespaceHandler extends NamespaceHandlerSupport {
+
+ @Override
+ public void init() {
+ registerBeanDefinitionParser("tracing-class", new TracingBeanDefinitionParser());
+ registerBeanDefinitionParser("tracing-package", new TracingPackageDefinitionParser());
+ registerBeanDefinitionParser("tracing", new TracingBeanPostProcessorParser());
+ }
+}
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/skywalking.xsd b/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/skywalking.xsd
new file mode 100644
index 000000000..28c034b22
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/skywalking.xsd
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/spring.handlers b/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/spring.handlers
new file mode 100644
index 000000000..4a1a195d9
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/spring.handlers
@@ -0,0 +1 @@
+http\://cloud.asiainfo.com/schema/skywalking=com.ai.cloud.skywalking.plugin.spring.schema.SWNamespaceHandler
\ No newline at end of file
diff --git a/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/spring.schemas b/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/spring.schemas
new file mode 100644
index 000000000..f26f1b043
--- /dev/null
+++ b/skywalking-sdk-plugin/spring-plugin/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1 @@
+http\://cloud.asiainfo.com/schema/skywalking/skywalking.xsd=META-INF/skywalking.xsd
\ No newline at end of file