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() {
NullBackgroundQuickPane nullBackgroundPane = new NullBackgroundQuickPane();
ColorBackgroundQuickPane colorBackgroundPane = new ColorBackgroundQuickPane();
ColorBackgroundQuickPane colorBackgroundPane = new ColorBackgroundQuickPane(true);
colorBackgroundPane.registerChangeListener(new UIObserverListener() {
@Override
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;
public ColorBackgroundQuickPane() {
public ColorBackgroundQuickPane(boolean supportTransparent) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
colorSelectBox = new NewColorSelectBox(100) {
colorSelectBox = new NewColorSelectBox(100, supportTransparent) {
@Override
public boolean shouldResponseChangeListener() {
// ColorBackgroundQuickPane注册监听器ChangeListenerImpl的逻辑不能丢,因为里面有修改字段backgroundChange的逻辑.
@ -33,6 +32,10 @@ public class ColorBackgroundQuickPane extends BackgroundQuickPane {
this.add(colorSelectBox, BorderLayout.NORTH);
}
public ColorBackgroundQuickPane() {
this(false);
}
public void populateBean(Background background) {
ColorBackground colorBackgroud = (ColorBackground) background;
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;
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.implementation.bytecode.assign.Assigner;
import com.fr.tolerance.FaultTolerance;
@ -15,19 +17,30 @@ import java.util.concurrent.Callable;
public class FaultToleranceAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static int onMethodEnter() throws Exception {
return 0;
public static boolean onMethodEnter(@Advice.Local("context") AdviceContext adviceContext) throws Exception {
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) 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);
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);
}
}

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;
import com.fr.concurrent.FineExecutors;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.general.GeneralUtils;
import com.fr.intelli.metrics.Compute;
import com.fr.intelli.metrics.RecordTask;
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;
@ -24,6 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.regex.Matcher;
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 int MIN_ERROR_CODE = 10000000;
public static ExecutorService executorService = FineExecutors.newCachedThreadPool(new
NamedThreadFactory(MonitorAdvice.class));
@Advice.OnMethodEnter
public static void onMethodEnter(@Advice.Origin Method method,
@ -75,24 +80,16 @@ public class MonitorAdvice implements DesignerAnalyzerAdvice {
measureObject.consume(consume);
measureObject.error(error);
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);
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);
}
String sessionID = null;
SessionProvider provider = SessionLocalManager.getSession();
if (provider != null) {
sessionID = provider.getSessionID();
}
RecordTask task = new RecordTask(measurable, measureObject, sessionID, newArgs);
executorService.submit(task);
}
} catch (Exception ignore) {
//埋点信息入库失败应该不能影响业务流程

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

@ -1,6 +1,10 @@
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
@ -18,18 +22,30 @@ public class Install4jStartupNotificationProvider implements FineStartupNotifica
@Override
public void registerStartupListener(Listener listener) {
boolean supported = false;
try {
supported = Class.forName("com.install4j.api.launcher.StartupNotification") != null;
} catch (Throwable ignored) {}
if (supported) {
StartupNotification.registerStartupListener(new StartupNotification.Listener() {
@Override
public void startupPerformed(String parameters) {
listener.startupPerformed(parameters);
}
});
Class<?> StartupNotificationListenerClass = Reflect.on("com.install4j.api.launcher.StartupNotification$Listener").type();
if (StartupNotificationListenerClass == null) {
return;
}
ListenerHandler mHandler = new ListenerHandler(listener);
Object listenerCallbackInstance = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { StartupNotificationListenerClass }, mHandler);
Reflect.on("com.install4j.api.launcher.StartupNotification").call("registerStartupListener", listenerCallbackInstance);
}
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 Color color;
private NewColorSelectPane colorPane = new NewColorSelectPane(false);
private NewColorSelectPane colorPane;
private UIObserverListener uiObserverListener;
private String newColorSelectBoxName = "";
private GlobalNameListener globalNameListener = null;
private boolean supportTransparent;
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();
}
@ -58,7 +65,7 @@ public class NewColorSelectBox extends AbstractSelectBox<Color> implements UIObs
*/
public JPanel initWindowPane(double preferredWidth) {
// 下拉的时候重新生成面板,以刷新最近使用颜色
colorPane = new NewColorSelectPane(false);
colorPane = new NewColorSelectPane(this.supportTransparent);
colorPane.setColor(this.getSelectObject());
colorPane.addChangeListener(new ChangeListener() {
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.dynamic.loading.ClassReloadingStrategy;
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.Test;
import java.util.concurrent.TimeUnit;
/**
* 测试一下通过 redefine 去处理代码时
* 相应的 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