Browse Source

feat: KERNEL-10354 bytebuddy / 加解密性能优化 @Harrison

1、FineAnalyzer部分延迟启动
2、FineAnalyzer 补充单元测试
3、补充优化开关
feature/x
Harrison 2 years ago
parent
commit
8b2b81926c
  1. 22
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzer.java
  2. 121
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java
  3. 12
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerAdvice.java
  4. 29
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/DBMonitorAdvice.java
  5. 35
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/FaultToleranceAdvice.java
  6. 32
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/FocusAdvice.java
  7. 159
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/MonitorAdvice.java
  8. 54
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/PerformancePointAdvice.java
  9. 81
      designer-base/src/test/java/com/fr/design/record/analyzer/BytebuddyRedefineTest.java
  10. 11
      designer-base/src/test/java/com/fr/design/record/analyzer/TestClass.java
  11. 29
      designer-base/src/test/java/com/fr/design/record/analyzer/TestModifyReturnAdvice.java
  12. 19
      designer-base/src/test/java/com/fr/design/record/analyzer/TestThrowExceptionAdvice.java
  13. 37
      designer-base/src/test/java/com/fr/design/record/analyzer/TestTransferValueAdvice.java
  14. 2
      designer-realize/src/main/java/com/fr/start/MainDesigner.java

22
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzer.java

@ -0,0 +1,22 @@
package com.fr.design.record.analyzer;
import com.fr.record.analyzer.AnalyzerConfiguration;
import com.fr.record.analyzer.AnalyzerUnit;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.record.analyzer.configuration.impl.RedefineAssemblyFactory;
/**
* created by Harrison on 2022/03/08
**/
public class DesignerAnalyzer {
private static final AnalyzerUnit ANALYZER = new AnalyzerUnit();
public static synchronized void init(AnalyzerAssemblyFactory factory, AnalyzerConfiguration... configurations) {
AnalyzerAssemblyFactory redefineFactory = factory.prepare(RedefineAssemblyFactory.getInstance());
ANALYZER.init(redefineFactory, configurations);
}
}

121
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java

@ -0,0 +1,121 @@
package com.fr.design.record.analyzer;
import com.fr.base.OptimizeUtil;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.record.analyzer.advice.DBMonitorAdvice;
import com.fr.design.record.analyzer.advice.FaultToleranceAdvice;
import com.fr.design.record.analyzer.advice.FocusAdvice;
import com.fr.design.record.analyzer.advice.MonitorAdvice;
import com.fr.design.record.analyzer.advice.PerformancePointAdvice;
import com.fr.intelli.metrics.Compute;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.PerformancePoint;
import com.fr.module.Activator;
import com.fr.module.extension.Prepare;
import com.fr.record.analyzer.AnalyzerConfiguration;
import com.fr.record.analyzer.AnalyzerKey;
import com.fr.record.analyzer.DBMetrics;
import com.fr.record.analyzer.FineAdviceTransformer;
import com.fr.record.analyzer.FineAnalyzer;
import com.fr.record.analyzer.advice.AnalyzerAdviceConfiguration;
import com.fr.record.analyzer.advice.AnalyzerAdviceKey;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.record.analyzer.configuration.FineAnalyzerAssemblyFactory;
import com.fr.stable.collections.CollectionUtils;
import com.fr.third.net.bytebuddy.matcher.ElementMatchers;
import com.fr.tolerance.FaultTolerance;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.ExecutorService;
/**
* created by Harrison on 2022/03/04
**/
public class DesignerAnalyzerActivator extends Activator implements Prepare {
@Override
public void start() {
OptimizeUtil.open(() -> {
ExecutorService es = newSingleThreadExecutor(new NamedThreadFactory("designer-analyzer", true));
try {
AnalyzerAssemblyFactory basicFactory = createBasicFactory();
// 兼容逻辑
List<AnalyzerConfiguration> backwardsConfigurations = findMutableBackwards(AnalyzerKey.KEY);
if (!CollectionUtils.isEmpty(backwardsConfigurations)) {
es.submit(() -> {
FineAnalyzer.init(basicFactory, backwardsConfigurations.toArray(new AnalyzerConfiguration[0]));
});
}
// 加入 retransform 部分的逻辑
List<AnalyzerAdviceConfiguration> adviceConfigurations = findMutable(AnalyzerAdviceKey.KEY);
if (!CollectionUtils.isEmpty(adviceConfigurations)) {
AnalyzerConfiguration[] configurations = convertConfigurations(adviceConfigurations);
es.submit(() -> {
DesignerAnalyzer.init(basicFactory, configurations);
});
}
} finally {
es.shutdown();
}
});
}
@NotNull
private AnalyzerConfiguration[] convertConfigurations(List<AnalyzerAdviceConfiguration> list) {
return list.stream()
.map((e) -> AnalyzerConfiguration.create(e.getMatcher(), new FineAdviceTransformer(e.getMatcher(), e.getAdviceClass())))
.toArray(AnalyzerConfiguration[]::new);
}
@Override
public void stop() {
}
@Override
public void prepare() {
addMutable(AnalyzerAdviceKey.KEY, AnalyzerAdviceConfiguration.create(
ElementMatchers.isAnnotatedWith(Focus.class),
FocusAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, AnalyzerAdviceConfiguration.create(
ElementMatchers.isAnnotatedWith(Compute.class),
MonitorAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, AnalyzerAdviceConfiguration.create(
ElementMatchers.isAnnotatedWith(DBMetrics.class),
DBMonitorAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, AnalyzerAdviceConfiguration.create(
ElementMatchers.isAnnotatedWith(PerformancePoint.class),
PerformancePointAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, AnalyzerAdviceConfiguration.create(
ElementMatchers.isAnnotatedWith(FaultTolerance.class),
FaultToleranceAdvice.class
));
}
private AnalyzerAssemblyFactory createBasicFactory() {
AnalyzerAssemblyFactory factory = findSingleton(AnalyzerAssemblyFactory.class);
FineAnalyzerAssemblyFactory basicFactory = new FineAnalyzerAssemblyFactory();
basicFactory.prepare(factory);
return basicFactory;
}
}

12
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerAdvice.java

@ -0,0 +1,12 @@
package com.fr.design.record.analyzer;
import com.fr.record.analyzer.advice.AnalyzerAdvice;
/**
* 仅作为标志
* 没有方法
*
* created by Harrison on 2022/03/04
**/
public interface DesignerAnalyzerAdvice extends AnalyzerAdvice {
}

29
designer-base/src/main/java/com/fr/design/record/analyzer/advice/DBMonitorAdvice.java

@ -0,0 +1,29 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.general.data.DataModel;
import com.fr.measure.DBMeterFactory;
import com.fr.measure.metric.DBMetric;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
/**
* created by Harrison on 2022/03/07
**/
public class DBMonitorAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result,
@Advice.Thrown(typing = Assigner.Typing.DYNAMIC) Exception e) {
if (args.length > 1 && args[1] instanceof DataModel) {
DBMetric meter = ((DataModel) args[1]).getMetric();
DBMeterFactory.getMeter().record(meter);
}
}
}

35
designer-base/src/main/java/com/fr/design/record/analyzer/advice/FaultToleranceAdvice.java

@ -0,0 +1,35 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import com.fr.tolerance.FaultTolerance;
import com.fr.tolerance.FaultToleranceFactory;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
/**
* created by Harrison on 2022/03/07
**/
public class FaultToleranceAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static int onMethodEnter(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args) throws Exception {
return 0;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result) throws Exception {
FaultTolerance faultTolerance = method.getAnnotation(FaultTolerance.class);
Callable<Object> callable = () -> method.invoke(self, args);
result = FaultToleranceFactory.getInstance().getScene(faultTolerance.scene()).getProcessor().execute(self, callable, args);
}
}

32
designer-base/src/main/java/com/fr/design/record/analyzer/advice/FocusAdvice.java

@ -0,0 +1,32 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.FocusPoint;
import com.fr.intelli.record.FocusPolicy;
import com.fr.log.counter.DefaultLimitedMetric;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
/**
* created by Harrison on 2022/03/07
**/
public class FocusAdvice implements DesignerAnalyzerAdvice {
private static final String FOCUS_POINT_ID_PREFIX = "function_";
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] arguments,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result) throws Exception {
if (FocusPolicy.IGNORE == result) {
return;
}
Focus focus = method.getAnnotation(Focus.class);
String id = FOCUS_POINT_ID_PREFIX + focus.id();
DefaultLimitedMetric.INSTANCE.submit(FocusPoint.create(id, focus.text(), focus.source()), id);
}
}

159
designer-base/src/main/java/com/fr/design/record/analyzer/advice/MonitorAdvice.java

@ -0,0 +1,159 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.general.GeneralUtils;
import com.fr.intelli.metrics.Compute;
import com.fr.intelli.metrics.SupervisoryConfig;
import com.fr.intelli.record.Measurable;
import com.fr.intelli.record.MeasureObject;
import com.fr.intelli.record.MeasureUnit;
import com.fr.intelli.record.MetricRegistry;
import com.fr.measure.DBMeterFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Session;
import com.fr.stable.web.SessionProvider;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import com.fr.web.core.SessionPoolManager;
import com.fr.web.session.SessionLocalManager;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* created by Harrison on 2022/03/07
**/
public class MonitorAdvice implements DesignerAnalyzerAdvice {
private static final Pattern P = Pattern.compile("-?\\d+");
private static final int MIN_ERROR_CODE = 10000000;
@Advice.OnMethodEnter
public static void onMethodEnter(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Local("startTime") Long startTime,
@Advice.Local("registeredSession") Boolean registeredSession) {
startTime = (System.currentTimeMillis());
registeredSession = (findSessionAnnotation(method, args));
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result,
@Advice.Thrown(typing = Assigner.Typing.DYNAMIC) Exception e,
@Advice.Local("startTime") Long startTime,
@Advice.Local("registeredSession") Boolean registeredSession) throws Exception {
String error = StringUtils.EMPTY;
try {
if (e != null) {
try {
error = getErrorContent(e);
} catch (Exception ignore) {
}
}
} finally {
try {
if (self instanceof Measurable) {
long consume = System.currentTimeMillis() - startTime;
Compute once = method.getAnnotation(Compute.class);
Measurable measurable = (Measurable) self;
MeasureObject measureObject = MeasureObject.create();
recordMemory(once, measurable, measureObject);
recordSQL(once, measureObject);
measureObject.consume(consume);
measureObject.error(error);
String id = UUID.randomUUID().toString();
List<Object> newArgs = new ArrayList<Object>(Arrays.asList(args));
newArgs.add(id);
recordSQLDetail(id);
Object message;
try {
message = measurable.durableEntity(measureObject, newArgs.toArray());
} catch (Throwable ignore) {
//埋点生成失败,降级逻辑
message = measurable.fallBackEntity();
}
if (message != null) {
SessionProvider provider = SessionLocalManager.getSession();
if (provider == null) {
MetricRegistry.getMetric().submit(message);
} else {
MetricRegistry.getMetric().submitAccumulativeData(provider.getSessionID(), message);
}
}
}
} catch (Exception ignore) {
//埋点信息入库失败应该不能影响业务流程
} finally {
if (registeredSession) {
// 如果上面记录了,这里就要释放
SessionLocalManager.releaseSession();
}
}
}
}
private static String getErrorContent(Exception e) {
int errorCode = GeneralUtils.objectToNumber(
extractCodeFromString(e.getMessage())
).intValue();
// 提取字符串中的第一个数字,最小的错误码为10000000
return e.getClass().getName() + ":" + (errorCode >= MIN_ERROR_CODE ? errorCode : StringUtils.EMPTY);
}
private static String extractCodeFromString(String errorMsg) {
Matcher m = P.matcher(errorMsg);
if (m.find()) {
return m.group();
}
return StringUtils.EMPTY;
}
private static void recordSQLDetail(String uuid) {
DBMeterFactory.getMeter().submit(uuid);
}
private static void recordSQL(Compute once, MeasureObject measureObject) {
if (SupervisoryConfig.getInstance().isEnableMeasureSql() && once.computeSql()) {
measureObject.sqlTime(SessionLocalManager.getSqlTime());
measureObject.sql(SessionLocalManager.getSql());
}
}
private static void recordMemory(Compute once, Measurable measurable, MeasureObject measureObject) {
if (SupervisoryConfig.getInstance().isEnableMeasureMemory() && once.computeMemory()) {
MeasureUnit unit = measurable.measureUnit();
measureObject.memory(unit.measureMemory());
}
}
private static boolean findSessionAnnotation(Method method, Object[] args) {
Annotation[][] all = method.getParameterAnnotations();
int len = ArrayUtils.getLength(args);
for (int i = 0; i < len; i++) {
Annotation[] current = all[i];
for (Annotation annotation : current) {
if (annotation.annotationType().equals(Session.class)) {
SessionLocalManager.setSession(
SessionPoolManager.getSessionIDInfor(GeneralUtils.objectToString(args[i]), SessionProvider.class));
return true;
}
}
}
return false;
}
}

54
designer-base/src/main/java/com/fr/design/record/analyzer/advice/PerformancePointAdvice.java

@ -0,0 +1,54 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.intelli.record.ConsumePoint;
import com.fr.intelli.record.MetricRegistry;
import com.fr.intelli.record.PerformancePoint;
import com.fr.intelli.record.PerformancePointRecord;
import com.fr.stable.StringUtils;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* created by Harrison on 2022/03/07
**/
public class PerformancePointAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodEnter
public static void onMethodEnter(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Local("startTime") Long startTime) {
startTime = (System.currentTimeMillis());
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result,
@Advice.Thrown(typing = Assigner.Typing.DYNAMIC) Exception e,
@Advice.Local("startTime") Long startTime) {
PerformancePoint point = method.getAnnotation(PerformancePoint.class);
String id = point.id();
long endTime = System.currentTimeMillis();
long consume = endTime - startTime;
if (self instanceof PerformancePointRecord) {
PerformancePointRecord measurable = (PerformancePointRecord) self;
List<Object> newArgs = new ArrayList<Object>(Arrays.asList(args));
ConsumePoint consumePoint = ConsumePoint.create(id, startTime, endTime, consume, point.source());
MetricRegistry.getMetric().submit(measurable.recordPoint(consumePoint, newArgs.toArray()));
} else {
if (StringUtils.isNotEmpty(id)) {
MetricRegistry.getMetric().submit(ConsumePoint.create(id, consume, point.source()));
}
}
}
}

81
designer-base/src/test/java/com/fr/design/record/analyzer/BytebuddyRedefineTest.java

@ -0,0 +1,81 @@
package com.fr.design.record.analyzer;
import com.fr.third.net.bytebuddy.ByteBuddy;
import com.fr.third.net.bytebuddy.agent.ByteBuddyAgent;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import com.fr.third.net.bytebuddy.matcher.ElementMatchers;
import org.junit.Test;
/**
* 测试一下通过 redefine 去处理代码时
* 相应的 advice 应该怎么写
*/
public class BytebuddyRedefineTest {
/**
* 测试一下是否可以直接抛出异常
*/
@Test
public void testThrowException() {
try {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestThrowExceptionAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
TestClass testClass = new TestClass();
testClass.testPrint();
} catch (Throwable throwable) {
}
}
/**
* 测试是否可以直接传值
*/
@Test
public void testTransferValue() {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestTransferValueAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
TestClass testClass = new TestClass();
String print = testClass.testPrint();
System.out.println(TestTransferValueAdvice.intField);
System.out.println(TestTransferValueAdvice.stringField);
System.out.println(TestTransferValueAdvice.objectField);
}
/**
* 测试是否可以改变返回值
*/
@Test
public void testModifyReturn() {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestModifyReturnAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
TestClass testClass = new TestClass();
String print = testClass.testPrint();
System.out.println(print);
}
}

11
designer-base/src/test/java/com/fr/design/record/analyzer/TestClass.java

@ -0,0 +1,11 @@
package com.fr.design.record.analyzer;
/**
* created by Harrison on 2022/03/04
**/
public class TestClass {
public String testPrint() {
return "";
}
}

29
designer-base/src/test/java/com/fr/design/record/analyzer/TestModifyReturnAdvice.java

@ -0,0 +1,29 @@
package com.fr.design.record.analyzer;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
/**
* created by Harrison on 2022/03/07
**/
public class TestModifyReturnAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static int onMethodEnter() throws Exception {
return 0;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result) throws Exception {
result = "[test]Modify Return Value";
}
}

19
designer-base/src/test/java/com/fr/design/record/analyzer/TestThrowExceptionAdvice.java

@ -0,0 +1,19 @@
package com.fr.design.record.analyzer;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
/**
* created by Harrison on 2022/03/07
**/
public class TestThrowExceptionAdvice {
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] arguments,
@Advice.Thrown(typing = Assigner.Typing.DYNAMIC) Exception e) throws Exception {
throw new RuntimeException("[test] throw exception in advice");
}
}

37
designer-base/src/test/java/com/fr/design/record/analyzer/TestTransferValueAdvice.java

@ -0,0 +1,37 @@
package com.fr.design.record.analyzer;
import com.fr.third.net.bytebuddy.asm.Advice;
/**
* created by Harrison on 2022/03/07
**/
public class TestTransferValueAdvice {
public static int intField;
public static String stringField;
public static Object objectField;
@Advice.OnMethodEnter
public static void onMethodEnter(@Advice.Local("int") int intField,
@Advice.Local("string") String stringField,
@Advice.Local("Object") Object objectField) {
intField = 10;
stringField = "[test]stringField";
objectField = "[test]objectField";
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.Local("int") int intField,
@Advice.Local("string") String stringField,
@Advice.Local("Object") Object objectField) throws Exception {
TestTransferValueAdvice.intField = intField;
TestTransferValueAdvice.stringField = stringField;
TestTransferValueAdvice.objectField = objectField;
}
}

2
designer-realize/src/main/java/com/fr/start/MainDesigner.java

@ -136,6 +136,8 @@ public class MainDesigner extends BaseDesigner {
}
FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", watch.getTime());
watch.stop();
}
/**

Loading…
Cancel
Save