原理图
- 采用模板方法设计模式定义插件增强逻辑
- 处理见证者机制
- 完成静态方法增强逻辑[允许修改参数]
- 完成构造方法增强逻辑[构造方法调用后增强,不可修改参数]
- 完成实例方法增强逻辑[允许修改参数]
类层次结构: AbstractClassEnhancePluginDefine定义插件的方法模板 ClassEnhancePluginDefine负责结合bytebuddy完成增强实现 ClassStaticMethodsEnhancePluginDefine完成静态方法插件定义 ClassInstanceMethodsEnhancePluginDefine完成构造和实例方法插件定义
见证者逻辑
使用场景 |
---|
当被拦截代码存在多版本,比如mysql-5.x-plugin和mysql-8.x-plugin,比如mysql8存在com.mysql.cj.interceptors.QueryInterceptor,则此时拦截如Statement.execute时,使用QueryInterceptor作为见证者,此时mysql-8.x-plugin只对mysql8的jdbc版本生效,对5,x的版本不生效【因为5.x的jdbc无QueryInterceptor类】,这就是见证者机制使用场景 |
插件增强原理图
源码分析一AbstractClassEnhancePluginDefine.define
public DynamicType.Builder<?> define(TypeDescription typeDescription,
DynamicType.Builder<?> builder, ClassLoader classLoader, EnhanceContext context) throws PluginException {
......闪出其他代码
见证者:对框架不同版本的处理方式,如果见证者不存在则不进行增强
String[] witnessClasses = witnessClasses();
if (witnessClasses != null) {
for (String witnessClass : witnessClasses) {
通过classloader对应的类型池判断见证者类在不在
if (!WitnessClassFinder.INSTANCE.exist(witnessClass, classLoader)) {
return null;
}
}
}
真正的增强逻辑 处理静态,构造和实例方法
DynamicType.Builder<?> newClassBuilder = this.enhance(typeDescription, builder, classLoader, context);
......闪出其他代码
return newClassBuilder;
}
源码分析一ClassEnhancePluginDefine.enhance
protected DynamicType.Builder<?> enhance(TypeDescription typeDescription,
DynamicType.Builder<?> newClassBuilder, ClassLoader classLoader,
EnhanceContext context) throws PluginException {
处理静态方法增强
newClassBuilder = this.enhanceClass(typeDescription, newClassBuilder, classLoader);
处理 构造方法 实例方法
newClassBuilder = this.enhanceInstance(typeDescription, newClassBuilder, classLoader, context);
return newClassBuilder;
}
源码分析一enhanceClass
- 与bytebuddy结合实现静态方法增强
- 如果覆盖参数使用bytebuddy工具api[Morph.Binder.install(OverrideCallable.class)]
- 区分是否boot插件,boot插件一般定义在bootstrap-plugins目录下
private DynamicType.Builder<?> enhanceClass(TypeDescription typeDescription,
DynamicType.Builder<?> newClassBuilder, ClassLoader classLoader) throws PluginException {
获取插件对应的静态方法拦截点 拦截的方法 和委托的拦截器
StaticMethodsInterceptPoint[] staticMethodsInterceptPoints = getStaticMethodsInterceptPoints();
拦截目标
String enhanceOriginClassName = typeDescription.getTypeName();
if (staticMethodsInterceptPoints == null || staticMethodsInterceptPoints.length == 0) {
return newClassBuilder;
}
for (StaticMethodsInterceptPoint staticMethodsInterceptPoint : staticMethodsInterceptPoints) {
String interceptor = staticMethodsInterceptPoint.getMethodsInterceptor();
...... 删除其他代码
StaticMethodsInterWithOverrideArgs 处理
if (staticMethodsInterceptPoint.isOverrideArgs()) {
if (isBootstrapInstrumentation()) {
getMethodsMatcher 拦截的方法
newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher()))
.intercept(
MethodDelegation.withDefaultConfiguration()
覆写参数
.withBinders(
Morph.Binder.install(OverrideCallable.class)
)
拦截器
.to(BootstrapInstrumentBoost.forInternalDelegateClass(interceptor))
);
} else {
newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher()))
.intercept(
MethodDelegation.withDefaultConfiguration()
.withBinders(
Morph.Binder.install(OverrideCallable.class)
)
增强交给inter进行 结合了bytebuddy的注解[参见bytebuddy]
.to(new StaticMethodsInterWithOverrideArgs(interceptor))
);
}
StaticMethodsInter处理
} else {
if (isBootstrapInstrumentation()) {
newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher()))
.intercept(
MethodDelegation.withDefaultConfiguration()
.to(BootstrapInstrumentBoost.forInternalDelegateClass(interceptor))
);
} else {
newClassBuilder = newClassBuilder.method(isStatic().and(staticMethodsInterceptPoint.getMethodsMatcher()))
.intercept(
MethodDelegation.withDefaultConfiguration()
.to(new StaticMethodsInter(interceptor))
);
}
}
}
return newClassBuilder;
}
源码分析一enhanceInstance
- 为被增强类实现EnhancedInstance接口并添加_$EnhancedClassField_ws属性
- 与bytebuddy结合处理构造方法[不支持覆盖参数,因为构造方法调用完成后调用拦截逻辑]
- 与bytebuddy结合处理实例方法[区分是否boot插件以及是否可以覆盖参数]
private DynamicType.Builder<?> enhanceInstance(TypeDescription typeDescription,
DynamicType.Builder<?> newClassBuilder, ClassLoader classLoader,
EnhanceContext context) throws PluginException {
...... 删除大量代码
所有代理类均有一个_$EnhancedClassField_ws属性
if (!context.isObjectExtended()) {
newClassBuilder = newClassBuilder.defineField(CONTEXT_ATTR_NAME, Object.class, ACC_PRIVATE | ACC_VOLATILE)
.implement(EnhancedInstance.class)
.intercept(FieldAccessor.ofField(CONTEXT_ATTR_NAME));
context.extendObjectCompleted();
}
增强构造方法
if (existedConstructorInterceptPoint) {
for (ConstructorInterceptPoint constructorInterceptPoint : constructorInterceptPoints) {
if (isBootstrapInstrumentation()) {
newClassBuilder = newClassBuilder.constructor(constructorInterceptPoint.getConstructorMatcher()).intercept(SuperMethodCall.INSTANCE
.andThen(MethodDelegation.withDefaultConfiguration()
.to(BootstrapInstrumentBoost.forInternalDelegateClass(constructorInterceptPoint.getConstructorInterceptor()))
)
);
} else {
newClassBuilder = newClassBuilder.constructor(constructorInterceptPoint.getConstructorMatcher()).intercept(SuperMethodCall.INSTANCE
.andThen(MethodDelegation.withDefaultConfiguration()
.to(new ConstructorInter(constructorInterceptPoint.getConstructorInterceptor(), classLoader))
)
);
}
}
}
增强实例方法
if (existedMethodsInterceptPoints) {
for (InstanceMethodsInterceptPoint instanceMethodsInterceptPoint : instanceMethodsInterceptPoints) {
String interceptor = instanceMethodsInterceptPoint.getMethodsInterceptor();
if (StringUtil.isEmpty(interceptor)) {
throw new EnhanceException("no InstanceMethodsAroundInterceptor define to enhance class " + enhanceOriginClassName);
}
ElementMatcher.Junction<MethodDescription> junction = not(isStatic()).and(instanceMethodsInterceptPoint.getMethodsMatcher());
if (instanceMethodsInterceptPoint instanceof DeclaredInstanceMethodsInterceptPoint) {
junction = junction.and(ElementMatchers.<MethodDescription>isDeclaredBy(typeDescription));
}
if (instanceMethodsInterceptPoint.isOverrideArgs()) {
if (isBootstrapInstrumentation()) {
newClassBuilder =
newClassBuilder.method(junction)
.intercept(
MethodDelegation.withDefaultConfiguration()
.withBinders(
Morph.Binder.install(OverrideCallable.class)
)
.to(BootstrapInstrumentBoost.forInternalDelegateClass(interceptor))
);
} else {
newClassBuilder =
newClassBuilder.method(junction)
.intercept(
MethodDelegation.withDefaultConfiguration()
.withBinders(
Morph.Binder.install(OverrideCallable.class)
)
.to(new InstMethodsInterWithOverrideArgs(interceptor, classLoader))
);
}
} else {
if (isBootstrapInstrumentation()) {
newClassBuilder =
newClassBuilder.method(junction)
.intercept(
MethodDelegation.withDefaultConfiguration()
.to(BootstrapInstrumentBoost.forInternalDelegateClass(interceptor))
);
} else {
newClassBuilder =
newClassBuilder.method(junction)
.intercept(
MethodDelegation.withDefaultConfiguration()
.to(new InstMethodsInter(interceptor, classLoader))
);
}
}
}
}
return newClassBuilder;
}
总结
- 增强类都有一个属性和一个接口实现: _$EnhancedClassField_ws与EnhancedInstance
- 增强类存在见证者机制witnessClasses,用来区分源码版本
- 构造方法增强部分的执行逻辑,发生在构造方法被调用后,所以不支持覆盖参数
- 字节码插桩的实现借助了bytebuddy工具
|