You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.8 KiB
91 lines
2.8 KiB
package com.fr.design.record.analyzer; |
|
|
|
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory; |
|
import com.fr.third.net.bytebuddy.agent.builder.AgentBuilder; |
|
|
|
import java.util.List; |
|
import java.util.Map; |
|
|
|
/** |
|
* 装配 Agent 为后置启动 |
|
* <p>必须在一个线程中处理 retransform 的事务,否则会阻塞整个的线程,导致效果不佳</p> |
|
* |
|
* created by Harrison on 2022/03/07 |
|
**/ |
|
public class DesignerAssemblyFactory implements AnalyzerAssemblyFactory<Void> { |
|
|
|
/** |
|
* 每次执行 1 个 class 的 retransform |
|
*/ |
|
private static final int FIXED_SIZE = 1; |
|
|
|
/** |
|
* 单位 ms |
|
* 每次间隔 500 ms, 执行一次 |
|
*/ |
|
private static final int DELAY_INTERVAL = 500; |
|
|
|
private final AgentBuilder.RedefinitionStrategy.BatchAllocator batchAllocator = AgentBuilder.RedefinitionStrategy.BatchAllocator.ForFixedSize.ofSize(FIXED_SIZE); |
|
|
|
private final AgentBuilder.RedefinitionStrategy.Listener redefinitionListener = new DelayListener(DELAY_INTERVAL); |
|
|
|
public static DesignerAssemblyFactory getInstance() { |
|
return DesignerAssemblyFactoryHolder.INSTANCE; |
|
} |
|
|
|
private static class DesignerAssemblyFactoryHolder { |
|
private static final DesignerAssemblyFactory INSTANCE = new DesignerAssemblyFactory(); |
|
} |
|
|
|
@Override |
|
public AnalyzerAssemblyFactory<Void> prepare(Void material) { |
|
|
|
return this; |
|
} |
|
|
|
@Override |
|
public AgentBuilder assembly(AgentBuilder raw) { |
|
|
|
return raw.disableClassFormatChanges() |
|
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) |
|
// 每次只 transform 一部分否则会导致 UI 变慢 |
|
.with(batchAllocator) |
|
.with(redefinitionListener) |
|
.with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE) |
|
.with(AgentBuilder.TypeStrategy.Default.REDEFINE); |
|
} |
|
|
|
private class DelayListener implements AgentBuilder.RedefinitionStrategy.Listener { |
|
|
|
/** |
|
* 单位 ms |
|
*/ |
|
private final int interval; |
|
|
|
public DelayListener(int interval) { |
|
this.interval = interval; |
|
} |
|
|
|
/** |
|
* 执行完后,等待一段时间再执行。 |
|
*/ |
|
@Override |
|
public void onBatch(int index, List<Class<?>> batch, List<Class<?>> types) { |
|
|
|
try { |
|
Thread.sleep(interval); |
|
} catch (Exception ignore) { |
|
} |
|
} |
|
|
|
@Override |
|
public Iterable<? extends List<Class<?>>> onError(int index, List<Class<?>> batch, Throwable throwable, List<Class<?>> types) { |
|
return null; |
|
} |
|
|
|
@Override |
|
public void onComplete(int amount, List<Class<?>> types, Map<List<Class<?>>, Throwable> failures) { |
|
|
|
} |
|
} |
|
}
|
|
|