完成Spring插件以及插件的测试
This commit is contained in:
parent
2c050c0597
commit
16aec017d1
|
|
@ -97,4 +97,26 @@
|
|||
<version>4.12</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<configuration>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
|||
public class SpringTagNamespaceHandler extends NamespaceHandlerSupport {
|
||||
@Override
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("tracing-bean", new TracingPatternParser());
|
||||
registerBeanDefinitionParser("trace", new TraceParser());
|
||||
registerBeanDefinitionParser("trace", new TracingPatternParser());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring;
|
||||
|
||||
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 TraceParser implements BeanDefinitionParser {
|
||||
|
||||
private final String TRACE_APPLICATION_BEAN_NAME = "TracingApplication";
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
if (parserContext.getRegistry().containsBeanDefinition(TRACE_APPLICATION_BEAN_NAME)) {
|
||||
// 只能存在一个
|
||||
throw new IllegalStateException("Duplicate spring bean id ");
|
||||
}
|
||||
boolean turnOn = Boolean.parseBoolean(element.getAttribute("turnOn"));
|
||||
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
|
||||
rootBeanDefinition.setLazyInit(false);
|
||||
rootBeanDefinition.setBeanClass(TracingEnhanceProcessor.class);
|
||||
rootBeanDefinition.getPropertyValues().addPropertyValue("turnOn", turnOn);
|
||||
parserContext.getRegistry().registerBeanDefinition(TRACE_APPLICATION_BEAN_NAME, rootBeanDefinition);
|
||||
return rootBeanDefinition;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,11 @@ 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 com.ai.cloud.skywalking.util.StringUtil;
|
||||
|
||||
import javassist.*;
|
||||
import javassist.bytecode.AnnotationsAttribute;
|
||||
import javassist.bytecode.ConstPool;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
|
@ -19,222 +20,226 @@ import org.springframework.context.ApplicationContextAware;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class TracingEnhanceProcessor implements DisposableBean, BeanPostProcessor, BeanFactoryPostProcessor, ApplicationContextAware {
|
||||
public class TracingEnhanceProcessor implements DisposableBean,
|
||||
BeanPostProcessor, BeanFactoryPostProcessor, ApplicationContextAware {
|
||||
|
||||
private final Set<TracingPattern> beanSet = new ConcurrentHashSet<TracingPattern>();
|
||||
private final Set<TracingPattern> beanSet = new ConcurrentHashSet<TracingPattern>();
|
||||
|
||||
private boolean turnOn;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(
|
||||
ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
beanSet.addAll(applicationContext.getBeansOfType(TracingPattern.class)
|
||||
.values());
|
||||
}
|
||||
|
||||
public boolean isTurnOn() {
|
||||
return turnOn;
|
||||
}
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void setTurnOn(boolean turnOn) {
|
||||
this.turnOn = turnOn;
|
||||
}
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
beanSet.addAll(applicationContext.getBeansOfType(TracingPattern.class).values());
|
||||
}
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
public enum MatchType {
|
||||
METHOD, PACKAGE, CLASS;
|
||||
}
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private boolean checkMatch(String value, String pattern, MatchType matchType) {
|
||||
boolean result;
|
||||
if ("*".equals(pattern)) {
|
||||
return true;
|
||||
}
|
||||
if (matchType == MatchType.PACKAGE) {
|
||||
if (pattern.endsWith(".*")) {
|
||||
String newPattern = pattern.substring(0,
|
||||
pattern.lastIndexOf(".*"));
|
||||
result = value.startsWith(newPattern);
|
||||
} else {
|
||||
result = value.equals(pattern);
|
||||
}
|
||||
} else {
|
||||
if (pattern.endsWith("*")) {
|
||||
String newPattern = pattern.substring(0,
|
||||
pattern.lastIndexOf("*"));
|
||||
result = value.startsWith(newPattern);
|
||||
} else {
|
||||
result = value.equals(pattern);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
String packageName = bean.getClass().getPackage().getName();
|
||||
String className = bean.getClass().getSimpleName();
|
||||
TracingPattern matchClassBean = null;
|
||||
boolean isMatch = false;
|
||||
for (TracingPattern tracingPattern : beanSet) {
|
||||
if (checkMatch(packageName, tracingPattern.getPackageName(),
|
||||
MatchType.PACKAGE)
|
||||
&& checkMatch(className, tracingPattern.getClassName(),
|
||||
MatchType.CLASS)) {
|
||||
isMatch = true;
|
||||
matchClassBean = tracingPattern;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!isMatch || matchClassBean == null) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public enum MatchType {
|
||||
METHOD, PACKAGE, CLASS;
|
||||
}
|
||||
// 符合规范
|
||||
try {
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
CtClass ctSource = pool.get(bean.getClass().getName());
|
||||
CtClass ctDestination = pool.makeClass(
|
||||
generateProxyClassName(bean), ctSource);
|
||||
// 拷贝所有的方法,
|
||||
copyAllFields(ctSource, ctDestination);
|
||||
// 拷贝所有的注解
|
||||
copyClassAnnotation(ctSource, ctDestination);
|
||||
// 拷贝所有的方法,并增强
|
||||
ConstPool cp = ctDestination.getClassFile().getConstPool();
|
||||
for (CtMethod m : ctSource.getDeclaredMethods()) {
|
||||
CtMethod newm = CtNewMethod.delegator(m, ctDestination);
|
||||
copyMethodAnnotation(cp, m, newm);
|
||||
// 是否符合规范,符合则增强
|
||||
if (checkMatch(m.getName(), matchClassBean.getMethod(),
|
||||
MatchType.METHOD)) {
|
||||
enhanceMethod(bean, newm);
|
||||
}
|
||||
ctDestination.addMethod(newm);
|
||||
}
|
||||
|
||||
private boolean checkMatch(String value, String pattern, MatchType matchType) {
|
||||
boolean result;
|
||||
if ("*".equals(pattern)) {
|
||||
return true;
|
||||
}
|
||||
if (matchType == MatchType.PACKAGE) {
|
||||
if (pattern.endsWith(".*")) {
|
||||
String newPattern = pattern.substring(0,
|
||||
pattern.lastIndexOf(".*"));
|
||||
result = value.startsWith(newPattern);
|
||||
} else {
|
||||
result = value.equals(pattern);
|
||||
}
|
||||
} else {
|
||||
if (pattern.endsWith("*")) {
|
||||
String newPattern = pattern.substring(0,
|
||||
pattern.lastIndexOf("*"));
|
||||
result = value.startsWith(newPattern);
|
||||
} else {
|
||||
result = value.equals(pattern);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Class<?> generateClass = ctDestination.toClass();
|
||||
Object newBean = generateClass.newInstance();
|
||||
BeanUtils.copyProperties(bean, newBean);
|
||||
return newBean;
|
||||
} catch (NotFoundException e) {
|
||||
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) {
|
||||
throw new IllegalStateException("Failed to instance class["
|
||||
+ beanName.getClass().getName() + "]", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Failed to access class["
|
||||
+ beanName.getClass().getName() + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (!turnOn) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
String packageName = bean.getClass().getPackage().getName();
|
||||
String className = bean.getClass().getSimpleName();
|
||||
TracingPattern matchClassBean = null;
|
||||
boolean isMatch = false;
|
||||
for (TracingPattern tracingPattern : beanSet) {
|
||||
if (checkMatch(packageName, tracingPattern.getPackageName(), MatchType.PACKAGE)
|
||||
&& checkMatch(className, tracingPattern.getClassName(), MatchType.CLASS)) {
|
||||
isMatch = true;
|
||||
matchClassBean = tracingPattern;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!isMatch || matchClassBean == null) {
|
||||
return bean;
|
||||
}
|
||||
private void copyMethodAnnotation(ConstPool cp, CtMethod m, CtMethod newm) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
//符合规范
|
||||
try {
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
CtClass ctSource = pool.get(bean.getClass().getName());
|
||||
CtClass ctDestination = pool.makeClass(generateProxyClassName(bean), ctSource);
|
||||
//拷贝所有的方法,
|
||||
copyAllFields(ctSource, ctDestination);
|
||||
// 拷贝所有的注解
|
||||
copyClassAnnotation(ctSource, ctDestination);
|
||||
//拷贝所有的方法,并增强
|
||||
ConstPool cp = ctDestination.getClassFile().getConstPool();
|
||||
for (CtMethod m : ctSource.getDeclaredMethods()) {
|
||||
CtMethod newm = CtNewMethod.copy(m, m.getName(), ctDestination, null);
|
||||
copyMethodAnnotation(cp, m, newm);
|
||||
// 是否符合规范,符合则增强
|
||||
if (checkMatch(m.getName(), matchClassBean.getMethod(), MatchType.METHOD)) {
|
||||
enhanceMethod(bean, newm);
|
||||
}
|
||||
ctDestination.addMethod(newm);
|
||||
}
|
||||
private String generateProxyClassName(Object bean) {
|
||||
return bean.getClass().getName() + "$EnhanceBySWTracing$"
|
||||
+ ThreadLocalRandom.current().nextInt(100);
|
||||
}
|
||||
|
||||
Class generateClass = ctDestination.toClass();
|
||||
Object newBean = generateClass.newInstance();
|
||||
BeanUtils.copyProperties(bean, newBean);
|
||||
return newBean;
|
||||
} catch (NotFoundException e) {
|
||||
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) {
|
||||
throw new IllegalStateException("Failed to instance class[" + beanName.getClass().getName() + "]", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Failed to access class[" + beanName.getClass().getName() + "]", e);
|
||||
}
|
||||
}
|
||||
private void copyAllFields(CtClass ctSource, CtClass ctDestination)
|
||||
throws CannotCompileException, NotFoundException {
|
||||
// copy fields
|
||||
ConstPool cp = ctDestination.getClassFile().getConstPool();
|
||||
for (CtField ctSourceField : ctSource.getDeclaredFields()) {
|
||||
CtClass fieldTypeClass = ClassPool.getDefault().get(
|
||||
ctSourceField.getType().getName());
|
||||
CtField ctField = new CtField(fieldTypeClass,
|
||||
ctSourceField.getName(), ctDestination);
|
||||
// with annotations
|
||||
copyAllFieldAnnotation(cp, ctSourceField, ctField);
|
||||
ctDestination.addField(ctField);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyMethodAnnotation(ConstPool cp, CtMethod m, CtMethod newm) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
private void copyAllFieldAnnotation(ConstPool cp, CtField ctSourceField,
|
||||
CtField ctDestinationField) throws CannotCompileException {
|
||||
AnnotationsAttribute invAnn = (AnnotationsAttribute) ctSourceField
|
||||
.getFieldInfo().getAttribute(AnnotationsAttribute.invisibleTag);
|
||||
AnnotationsAttribute visAnn = (AnnotationsAttribute) ctSourceField
|
||||
.getFieldInfo().getAttribute(AnnotationsAttribute.visibleTag);
|
||||
|
||||
private String generateProxyClassName(Object bean) {
|
||||
return bean.getClass().getName() + "$EnhanceBySWTracing$" + ThreadLocalRandom.current().nextInt(100);
|
||||
}
|
||||
if (invAnn != null) {
|
||||
ctDestinationField.getFieldInfo().addAttribute(
|
||||
invAnn.copy(cp, null));
|
||||
}
|
||||
if (visAnn != null) {
|
||||
ctDestinationField.getFieldInfo().addAttribute(
|
||||
visAnn.copy(cp, null));
|
||||
}
|
||||
}
|
||||
|
||||
private void copyAllFields(CtClass ctSource, CtClass ctDestination) throws CannotCompileException, NotFoundException {
|
||||
// copy fields
|
||||
ConstPool cp = ctDestination.getClassFile().getConstPool();
|
||||
for (CtField ctSourceField : ctSource.getDeclaredFields()) {
|
||||
CtClass fieldTypeClass = ClassPool.getDefault().get(ctSourceField.getType().getName());
|
||||
CtField ctField = new CtField(fieldTypeClass, ctSourceField.getName(), ctDestination);
|
||||
//with annotations
|
||||
copyAllFieldAnnotation(cp, ctSourceField, ctField);
|
||||
ctDestination.addField(ctField);
|
||||
}
|
||||
}
|
||||
private void copyClassAnnotation(CtClass ctSource, CtClass ctDestination) {
|
||||
ConstPool cp = ctDestination.getClassFile().getConstPool();
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
private void copyAllFieldAnnotation(ConstPool cp, CtField ctSourceField, CtField ctDestinationField) throws CannotCompileException {
|
||||
AnnotationsAttribute invAnn = (AnnotationsAttribute) ctSourceField.getFieldInfo().getAttribute(
|
||||
AnnotationsAttribute.invisibleTag);
|
||||
AnnotationsAttribute visAnn = (AnnotationsAttribute) ctSourceField.getFieldInfo().getAttribute(
|
||||
AnnotationsAttribute.visibleTag);
|
||||
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()
|
||||
+ "();\n___sender.beforeSend"
|
||||
+ generateBeforeSendParameter(bean, method) + "\n");
|
||||
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);
|
||||
}
|
||||
|
||||
if (invAnn != null) {
|
||||
ctDestinationField.getFieldInfo().addAttribute(invAnn.copy(cp, null));
|
||||
}
|
||||
if (visAnn != null) {
|
||||
ctDestinationField.getFieldInfo().addAttribute(visAnn.copy(cp, null));
|
||||
}
|
||||
}
|
||||
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 (CtClass param : method.getParameterTypes()) {
|
||||
builder.append(param.getSimpleName() + ",");
|
||||
}
|
||||
if (method.getParameterTypes().length > 0) {
|
||||
builder = builder.delete(builder.length() - 1, builder.length());
|
||||
}
|
||||
builder.append(")");
|
||||
builder.append("\").spanType('M').build());");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private void copyClassAnnotation(CtClass ctSource, CtClass ctDestination) {
|
||||
ConstPool cp = ctDestination.getClassFile().getConstPool();
|
||||
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));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
|
||||
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 generateBeforeSendParameter(Object bean, CtMethod method) throws NotFoundException {
|
||||
StringBuilder builder = new StringBuilder("(" + Identification.class.getName() + ".newBuilder().viewPoint(\""
|
||||
+ bean.getClass().getName() + "." + method.getName());
|
||||
builder.append("(");
|
||||
for (CtClass param : method.getParameterTypes()) {
|
||||
builder.append(param.getSimpleName() + ",");
|
||||
}
|
||||
if (method.getParameterTypes().length > 0) {
|
||||
builder = builder.delete(builder.length() - 1, builder.length());
|
||||
}
|
||||
builder.append(")");
|
||||
builder.append("\").spanType('M').build());");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
private boolean isClassNameMatch(Object bean, String tracingClassBean) {
|
||||
//
|
||||
String classNamePrefix = tracingClassBean;
|
||||
if (tracingClassBean.endsWith("*")) {
|
||||
classNamePrefix = tracingClassBean.substring(0, tracingClassBean.indexOf('*'));
|
||||
}
|
||||
return bean.getClass().getSimpleName().startsWith(classNamePrefix);
|
||||
}
|
||||
|
||||
private boolean isPackageMatch(Object bean, String packageName) {
|
||||
return bean.getClass().getPackage().equals(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ import org.w3c.dom.NamedNodeMap;
|
|||
import org.w3c.dom.Node;
|
||||
|
||||
public class TracingPatternParser implements BeanDefinitionParser {
|
||||
|
||||
private final String TRACE_PROCESSOR_BEAN_NAME = "TraceProcessorBean";
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
// 获取Method并处理
|
||||
|
|
@ -48,7 +51,14 @@ public class TracingPatternParser implements BeanDefinitionParser {
|
|||
beanDefinition.getPropertyValues().add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!parserContext.getRegistry().containsBeanDefinition(TRACE_PROCESSOR_BEAN_NAME)){
|
||||
RootBeanDefinition traceProcessorBeanDefinition = new RootBeanDefinition();
|
||||
traceProcessorBeanDefinition.setBeanClass(TracingEnhanceProcessor.class);
|
||||
traceProcessorBeanDefinition.setLazyInit(false);
|
||||
parserContext.getRegistry().registerBeanDefinition(TRACE_PROCESSOR_BEAN_NAME, traceProcessorBeanDefinition);
|
||||
}
|
||||
|
||||
return beanDefinition;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
package com.ai.cloud.skywalking.plugin.spring.extansion;
|
||||
|
||||
public class SpringExtensionFactory {
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
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());
|
||||
}
|
||||
}
|
||||
|
|
@ -11,11 +11,13 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<E>, Seri
|
|||
private static final Object PRESENT = new Object();
|
||||
private final ConcurrentHashMap<E, Object> map;
|
||||
|
||||
public ConcurrentHashSet() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConcurrentHashSet() {
|
||||
this.map = new ConcurrentHashMap();
|
||||
}
|
||||
|
||||
public ConcurrentHashSet(int initialCapacity) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConcurrentHashSet(int initialCapacity) {
|
||||
this.map = new ConcurrentHashMap(initialCapacity);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<xsd:schema xmlns="http://cloud.asiainfo.com/schema/skywalking"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://cloud.asiainfo.com/schema/skywalking">
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://cloud.asiainfo.com/schema/skywalking">
|
||||
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
|
||||
<xsd:element name="tracing-bean">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="method" type="xsd:string" use="optional" default="*"/>
|
||||
<xsd:attribute name="packageName" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="className" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="trace">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="turnOn" use="optional" default="true" type="xsd:boolean"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="trace" type="traceType">
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="traceType">
|
||||
<xsd:attribute name="packageName" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="className" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="method" type="xsd:string" use="optional"
|
||||
default="*" />
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
|
|
@ -14,4 +14,4 @@ public class TestBean {
|
|||
TestBean testBean = classPathXmlApplicationContext.getBean(TestBean.class);
|
||||
testBean.testPrintln("Hello World");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,14 +4,11 @@
|
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:skywalking="http://cloud.asiainfo.com/schema/skywalking"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://cloud.asiainfo.com/schema/skywalking
|
||||
http://cloud.asiainfo.com/schema/skywalking/skywalking.xsd">
|
||||
|
||||
<skywalking:trace/>
|
||||
|
||||
<!--<skywalking:tracing-bean className="AppTest01" method="testPrintln*" packageName="*"/>-->
|
||||
|
||||
|
||||
<skywalking:trace className="TestBean" method="testPrintln*" packageName="*"/>
|
||||
<bean class="com.ai.cloud.skywalking.plugin.spring.TestBean" />
|
||||
|
||||
</beans>
|
||||
Loading…
Reference in New Issue