Browse Source

Merge remote-tracking branch 'origin/feature/x' into feature/x

feature/x
pengda 3 years ago
parent
commit
94bede587c
  1. 2
      designer-base/src/main/java/com/fr/design/gui/style/ReportBackgroundSpecialPane.java
  2. 9
      designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ColorBackgroundQuickPane.java
  3. 21
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/FaultToleranceAdvice.java
  4. 29
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/MonitorAdvice.java
  5. 42
      designer-base/src/main/java/com/fr/design/startup/Install4jStartupNotificationProvider.java
  6. 13
      designer-base/src/main/java/com/fr/design/style/color/NewColorSelectBox.java
  7. 56
      designer-base/src/test/java/com/fr/design/record/analyzer/BytebuddyRedefineTest.java
  8. 50
      designer-base/src/test/java/com/fr/design/record/analyzer/TestCallableAdvice.java
  9. 15
      designer-base/src/test/java/com/fr/design/record/analyzer/TestCallableHelper.java

2
designer-base/src/main/java/com/fr/design/gui/style/ReportBackgroundSpecialPane.java

@ -29,7 +29,7 @@ public class ReportBackgroundSpecialPane extends BackgroundPane {
protected BackgroundQuickPane[] supportKindsOfBackgroundUI() { protected BackgroundQuickPane[] supportKindsOfBackgroundUI() {
NullBackgroundQuickPane nullBackgroundPane = new NullBackgroundQuickPane(); NullBackgroundQuickPane nullBackgroundPane = new NullBackgroundQuickPane();
ColorBackgroundQuickPane colorBackgroundPane = new ColorBackgroundQuickPane(); ColorBackgroundQuickPane colorBackgroundPane = new ColorBackgroundQuickPane(true);
colorBackgroundPane.registerChangeListener(new UIObserverListener() { colorBackgroundPane.registerChangeListener(new UIObserverListener() {
@Override @Override
public void doChange() { public void doChange() {

9
designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ColorBackgroundQuickPane.java

@ -16,10 +16,9 @@ public class ColorBackgroundQuickPane extends BackgroundQuickPane {
private NewColorSelectBox colorSelectBox; private NewColorSelectBox colorSelectBox;
public ColorBackgroundQuickPane(boolean supportTransparent) {
public ColorBackgroundQuickPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setLayout(FRGUIPaneFactory.createBorderLayout());
colorSelectBox = new NewColorSelectBox(100) { colorSelectBox = new NewColorSelectBox(100, supportTransparent) {
@Override @Override
public boolean shouldResponseChangeListener() { public boolean shouldResponseChangeListener() {
// ColorBackgroundQuickPane注册监听器ChangeListenerImpl的逻辑不能丢,因为里面有修改字段backgroundChange的逻辑. // ColorBackgroundQuickPane注册监听器ChangeListenerImpl的逻辑不能丢,因为里面有修改字段backgroundChange的逻辑.
@ -33,6 +32,10 @@ public class ColorBackgroundQuickPane extends BackgroundQuickPane {
this.add(colorSelectBox, BorderLayout.NORTH); this.add(colorSelectBox, BorderLayout.NORTH);
} }
public ColorBackgroundQuickPane() {
this(false);
}
public void populateBean(Background background) { public void populateBean(Background background) {
ColorBackground colorBackgroud = (ColorBackground) background; ColorBackground colorBackgroud = (ColorBackground) background;
populateColor(colorBackgroud.getColor()); populateColor(colorBackgroud.getColor());

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

@ -1,6 +1,8 @@
package com.fr.design.record.analyzer.advice; package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice; import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.record.analyzer.advice.AdviceContext;
import com.fr.record.analyzer.advice.DefaultAdviceCallable;
import com.fr.third.net.bytebuddy.asm.Advice; import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner; import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import com.fr.tolerance.FaultTolerance; import com.fr.tolerance.FaultTolerance;
@ -15,19 +17,30 @@ import java.util.concurrent.Callable;
public class FaultToleranceAdvice implements DesignerAnalyzerAdvice { public class FaultToleranceAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class) @Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static int onMethodEnter() throws Exception { public static boolean onMethodEnter(@Advice.Local("context") AdviceContext adviceContext) throws Exception {
return 0;
adviceContext = AdviceContext
.builder()
.onAdviceCall()
.build();
// 如果是切面调用,则忽视当前方法
return adviceContext.isOnAdviceCall();
} }
@Advice.OnMethodExit(onThrowable = Exception.class) @Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self, public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method, @Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result) throws Exception { @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result,
@Advice.Local("context")AdviceContext adviceContext) throws Exception {
// 如果是切面调用,则忽视不继续 exit
if (adviceContext != null && adviceContext.isOnAdviceCall()) {
return;
}
FaultTolerance faultTolerance = method.getAnnotation(FaultTolerance.class); FaultTolerance faultTolerance = method.getAnnotation(FaultTolerance.class);
Callable<Object> callable = () -> method.invoke(self, args); Callable<Object> callable = new DefaultAdviceCallable<>(self, method, args);
result = FaultToleranceFactory.getInstance().getScene(faultTolerance.scene()).getProcessor().execute(self, callable, args); result = FaultToleranceFactory.getInstance().getScene(faultTolerance.scene()).getProcessor().execute(self, callable, args);
} }
} }

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

@ -1,13 +1,15 @@
package com.fr.design.record.analyzer.advice; package com.fr.design.record.analyzer.advice;
import com.fr.concurrent.FineExecutors;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice; import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.general.GeneralUtils; import com.fr.general.GeneralUtils;
import com.fr.intelli.metrics.Compute; import com.fr.intelli.metrics.Compute;
import com.fr.intelli.metrics.RecordTask;
import com.fr.intelli.metrics.SupervisoryConfig; import com.fr.intelli.metrics.SupervisoryConfig;
import com.fr.intelli.record.Measurable; import com.fr.intelli.record.Measurable;
import com.fr.intelli.record.MeasureObject; import com.fr.intelli.record.MeasureObject;
import com.fr.intelli.record.MeasureUnit; import com.fr.intelli.record.MeasureUnit;
import com.fr.intelli.record.MetricRegistry;
import com.fr.measure.DBMeterFactory; import com.fr.measure.DBMeterFactory;
import com.fr.stable.ArrayUtils; import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
@ -24,6 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -34,6 +37,8 @@ public class MonitorAdvice implements DesignerAnalyzerAdvice {
private static final Pattern P = Pattern.compile("-?\\d+"); private static final Pattern P = Pattern.compile("-?\\d+");
private static final int MIN_ERROR_CODE = 10000000; private static final int MIN_ERROR_CODE = 10000000;
public static ExecutorService executorService = FineExecutors.newCachedThreadPool(new
NamedThreadFactory(MonitorAdvice.class));
@Advice.OnMethodEnter @Advice.OnMethodEnter
public static void onMethodEnter(@Advice.Origin Method method, public static void onMethodEnter(@Advice.Origin Method method,
@ -75,24 +80,16 @@ public class MonitorAdvice implements DesignerAnalyzerAdvice {
measureObject.consume(consume); measureObject.consume(consume);
measureObject.error(error); measureObject.error(error);
String id = UUID.randomUUID().toString(); String id = UUID.randomUUID().toString();
List<Object> newArgs = new ArrayList<Object>(Arrays.asList(args)); List<Object> newArgs = new ArrayList<>(Arrays.asList(args));
newArgs.add(id); newArgs.add(id);
recordSQLDetail(id); recordSQLDetail(id);
Object message; String sessionID = null;
try { SessionProvider provider = SessionLocalManager.getSession();
message = measurable.durableEntity(measureObject, newArgs.toArray()); if (provider != null) {
} catch (Throwable ignore) { sessionID = provider.getSessionID();
//埋点生成失败,降级逻辑
message = measurable.fallBackEntity();
}
if (message != null) {
SessionProvider provider = SessionLocalManager.getSession();
if (provider == null) {
MetricRegistry.getMetric().submit(message);
} else {
MetricRegistry.getMetric().submitAccumulativeData(provider.getSessionID(), message);
}
} }
RecordTask task = new RecordTask(measurable, measureObject, sessionID, newArgs);
executorService.submit(task);
} }
} catch (Exception ignore) { } catch (Exception ignore) {
//埋点信息入库失败应该不能影响业务流程 //埋点信息入库失败应该不能影响业务流程

42
designer-base/src/main/java/com/fr/design/startup/Install4jStartupNotificationProvider.java

@ -1,6 +1,10 @@
package com.fr.design.startup; package com.fr.design.startup;
import com.install4j.api.launcher.StartupNotification; import com.fr.invoke.Reflect;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/** /**
* @author Starryi * @author Starryi
@ -18,18 +22,30 @@ public class Install4jStartupNotificationProvider implements FineStartupNotifica
@Override @Override
public void registerStartupListener(Listener listener) { public void registerStartupListener(Listener listener) {
boolean supported = false; Class<?> StartupNotificationListenerClass = Reflect.on("com.install4j.api.launcher.StartupNotification$Listener").type();
try { if (StartupNotificationListenerClass == null) {
supported = Class.forName("com.install4j.api.launcher.StartupNotification") != null; return;
} catch (Throwable ignored) {} }
if (supported) { ListenerHandler mHandler = new ListenerHandler(listener);
StartupNotification.registerStartupListener(new StartupNotification.Listener() { Object listenerCallbackInstance = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { StartupNotificationListenerClass }, mHandler);
@Override Reflect.on("com.install4j.api.launcher.StartupNotification").call("registerStartupListener", listenerCallbackInstance);
public void startupPerformed(String parameters) { }
listener.startupPerformed(parameters);
} private static class ListenerHandler implements InvocationHandler {
}); private final Listener listener;
public ListenerHandler(Listener listener) {
this.listener = listener;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (args[0] instanceof String) {
String parameters = (String) args[0];
listener.startupPerformed(parameters);
}
return null;
} }
} }
} }

13
designer-base/src/main/java/com/fr/design/style/color/NewColorSelectBox.java

@ -20,13 +20,20 @@ public class NewColorSelectBox extends AbstractSelectBox<Color> implements UIObs
private static final long serialVersionUID = 2782150678943960557L; private static final long serialVersionUID = 2782150678943960557L;
private Color color; private Color color;
private NewColorSelectPane colorPane = new NewColorSelectPane(false); private NewColorSelectPane colorPane;
private UIObserverListener uiObserverListener; private UIObserverListener uiObserverListener;
private String newColorSelectBoxName = ""; private String newColorSelectBoxName = "";
private GlobalNameListener globalNameListener = null; private GlobalNameListener globalNameListener = null;
private boolean supportTransparent;
public NewColorSelectBox(int preferredWidth) { public NewColorSelectBox(int preferredWidth) {
initBox(preferredWidth); this(preferredWidth, false);
}
public NewColorSelectBox(int preferredWidth, boolean supportTransparent) {
this.colorPane = new NewColorSelectPane(supportTransparent);
this.supportTransparent = supportTransparent;
initBox(preferredWidth);
iniListener(); iniListener();
} }
@ -58,7 +65,7 @@ public class NewColorSelectBox extends AbstractSelectBox<Color> implements UIObs
*/ */
public JPanel initWindowPane(double preferredWidth) { public JPanel initWindowPane(double preferredWidth) {
// 下拉的时候重新生成面板,以刷新最近使用颜色 // 下拉的时候重新生成面板,以刷新最近使用颜色
colorPane = new NewColorSelectPane(false); colorPane = new NewColorSelectPane(this.supportTransparent);
colorPane.setColor(this.getSelectObject()); colorPane.setColor(this.getSelectObject());
colorPane.addChangeListener(new ChangeListener() { colorPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {

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

@ -5,9 +5,12 @@ import com.fr.third.net.bytebuddy.agent.ByteBuddyAgent;
import com.fr.third.net.bytebuddy.asm.Advice; import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.dynamic.loading.ClassReloadingStrategy; import com.fr.third.net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import com.fr.third.net.bytebuddy.matcher.ElementMatchers; import com.fr.third.net.bytebuddy.matcher.ElementMatchers;
import com.fr.third.org.apache.commons.lang3.time.StopWatch;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.util.concurrent.TimeUnit;
/** /**
* 测试一下通过 redefine 去处理代码时 * 测试一下通过 redefine 去处理代码时
* 相应的 advice 应该怎么写 * 相应的 advice 应该怎么写
@ -80,4 +83,57 @@ public class BytebuddyRedefineTest {
} }
@Test
public void testCallable() throws Exception {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestCallableAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
TestClass testClass = new TestClass();
String print = testClass.testPrint();
Assert.assertEquals("[test]Callable", print);
}
@Test
public void testCallablePerformance() throws Exception {
// 千
int loop = 1000;
StopWatch stopWatch = new StopWatch();
stopWatch.start();
TestClass rawClass = new TestClass();
for (int i = 0; i < loop; i++) {
rawClass.testPrint();
}
System.out.printf("raw class run %s cost %s ms \n", loop, stopWatch.getTime(TimeUnit.MILLISECONDS));
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestCallableAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
stopWatch.reset();
stopWatch.start();
TestClass retransformClass = new TestClass();
for (int i = 0; i < loop; i++) {
retransformClass.testPrint();
}
System.out.printf("retransformClass class run %s cost %s ms \n", loop, stopWatch.getTime(TimeUnit.MILLISECONDS));
Assert.assertEquals("[test]Callable", retransformClass.testPrint());
}
} }

50
designer-base/src/test/java/com/fr/design/record/analyzer/TestCallableAdvice.java

@ -0,0 +1,50 @@
package com.fr.design.record.analyzer;
import com.fr.record.analyzer.advice.AdviceCallable;
import com.fr.record.analyzer.advice.AdviceContext;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import com.fr.tolerance.FaultTolerance;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
/**
* created by Harrison on 2022/03/09
**/
public class TestCallableAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static boolean onMethodEnter(@Advice.Local("context")AdviceContext adviceContext) {
adviceContext = AdviceContext
.builder()
.onAdviceCall()
.build();
// 如果是切面调用,则忽视当前方法
return adviceContext.isOnAdviceCall();
}
@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.Local("context") AdviceContext adviceContext) throws Exception {
// 如果是切面调用,则忽视不继续 exit
if (adviceContext != null && adviceContext.isOnAdviceCall()) {
return;
}
FaultTolerance faultTolerance = method.getAnnotation(FaultTolerance.class);
Callable<Object> callable = new AdviceCallable<Object>() {
@Override
public Object call() throws Exception {
return method.invoke(self, args);
}
};
result = TestCallableHelper.test(callable);
}
}

15
designer-base/src/test/java/com/fr/design/record/analyzer/TestCallableHelper.java

@ -0,0 +1,15 @@
package com.fr.design.record.analyzer;
import java.util.concurrent.Callable;
/**
* created by Harrison on 2022/03/09
**/
public class TestCallableHelper {
public static String test(Callable<Object> callable) throws Exception {
callable.call();
return "[test]Callable";
}
}
Loading…
Cancel
Save