66import java .lang .instrument .Instrumentation ;
77import java .util .ArrayList ;
88import java .util .Collection ;
9+ import java .util .HashMap ;
910import java .util .List ;
11+ import java .util .Map ;
1012import java .util .Properties ;
1113import java .util .jar .JarEntry ;
1214import java .util .jar .JarFile ;
@@ -85,14 +87,47 @@ public InstrumentParseResult build() throws IOException {
8587 InputStream inputStream = jarFile .getInputStream (propertiesEntry );
8688 Properties properties = PropertiesUtils .loadNotNull (inputStream );
8789
88- String triggerRetransformValue = properties .getProperty ("triggerRetransform" , "false" ); // 使用默认值避免null值
90+ String triggerRetransformValue = properties .getProperty ("triggerRetransform" , "false" );
8991 boolean triggerRetransform = Boolean .parseBoolean (triggerRetransformValue );
90- for (Pair <String , byte []> pair : readClassBytes (properties , INSTRUMENT , jarFile )) {
91- parse (result , pair .second , triggerRetransform );
92+
93+ // 解析新格式:instrument.{key}=... 和 define.{key}=...
94+ Map <String , List <Pair <String , byte []>>> instrumentMap = new HashMap <String , List <Pair <String , byte []>>>();
95+ Map <String , List <Pair <String , byte []>>> defineMap = new HashMap <String , List <Pair <String , byte []>>>();
96+
97+ for (String key : properties .stringPropertyNames ()) {
98+ if (key .startsWith ("instrument." )) {
99+ String configKey = key .substring ("instrument." .length ());
100+ List <Pair <String , byte []>> classBytesList = readClassBytes (properties , key , jarFile );
101+ if (!classBytesList .isEmpty ()) {
102+ instrumentMap .put (configKey , classBytesList );
103+ }
104+ } else if (key .startsWith ("define." )) {
105+ String configKey = key .substring ("define." .length ());
106+ List <Pair <String , byte []>> classBytesList = readClassBytes (properties , key , jarFile );
107+ if (!classBytesList .isEmpty ()) {
108+ defineMap .put (configKey , classBytesList );
109+ }
110+ } else if (key .equals (INSTRUMENT )) {
111+ // 兼容旧格式:instrument=...
112+ for (Pair <String , byte []> pair : readClassBytes (properties , INSTRUMENT , jarFile )) {
113+ parse (result , pair .second , triggerRetransform , null );
114+ }
115+ } else if (key .equals (DEFINE )) {
116+ // 兼容旧格式:define=...(全局 define,会被添加到所有 instrument)
117+ for (Pair <String , byte []> pair : readClassBytes (properties , DEFINE , jarFile )) {
118+ result .addDefineClass (pair .first , pair .second );
119+ }
120+ }
92121 }
93-
94- for (Pair <String , byte []> pair : readClassBytes (properties , DEFINE , jarFile )) {
95- result .addDefineClass (pair .first , pair .second );
122+
123+ // 处理新格式的 instrument 和 define 关联
124+ for (Map .Entry <String , List <Pair <String , byte []>>> entry : instrumentMap .entrySet ()) {
125+ String configKey = entry .getKey ();
126+ List <Pair <String , byte []>> defineClassList = defineMap .get (configKey );
127+
128+ for (Pair <String , byte []> instrumentPair : entry .getValue ()) {
129+ parse (result , instrumentPair .second , triggerRetransform , defineClassList );
130+ }
96131 }
97132 }
98133
@@ -103,7 +138,7 @@ public InstrumentParseResult build() throws IOException {
103138
104139 // 处理单独设置 byte[]
105140 for (byte [] classBytes : instrumentClassList ) {
106- parse (result , classBytes , false );
141+ parse (result , classBytes , false , null );
107142 }
108143
109144 return result ;
@@ -137,7 +172,7 @@ private List<Pair<String, byte[]>> readClassBytes(Properties properties, String
137172 return result ;
138173 }
139174
140- private void parse (InstrumentParseResult result , byte [] classBytes , boolean triggerRetransform ) {
175+ private void parse (InstrumentParseResult result , byte [] classBytes , boolean triggerRetransform , List < Pair < String , byte []>> defineClassList ) {
141176 ClassNode classNode = AsmUtils .toClassNode (classBytes );
142177
143178 if (!AsmUtils .fitCurrentJvmMajorVersion (classNode )) {
@@ -158,28 +193,45 @@ private void parse(InstrumentParseResult result, byte[] classBytes, boolean trig
158193
159194 if (matchClassList != null && !matchClassList .isEmpty ()) {
160195 SimpleClassMatcher classMatcher = new SimpleClassMatcher (matchClassList );
161- result .addInstrumentConfig (new InstrumentConfig (classNode , classMatcher , updateMajorVersion , triggerRetransform ));
196+ InstrumentConfig config = new InstrumentConfig (classNode , classMatcher , updateMajorVersion , triggerRetransform );
197+ addDefineConfigs (config , defineClassList );
198+ result .addInstrumentConfig (config );
162199 }
163200
164201 List <String > matchSuperclassList = AsmAnnotationUtils .queryAnnotationArrayValue (classNode .visibleAnnotations ,
165202 Type .getDescriptor (Instrument .class ), "Superclass" );
166203
167204 if (!matchSuperclassList .isEmpty ()) {
168205 SimpleSubclassMatcher matcher = new SimpleSubclassMatcher (matchSuperclassList );
169- result .addInstrumentConfig (new InstrumentConfig (classNode , matcher , updateMajorVersion , triggerRetransform ));
206+ InstrumentConfig config = new InstrumentConfig (classNode , matcher , updateMajorVersion , triggerRetransform );
207+ addDefineConfigs (config , defineClassList );
208+ result .addInstrumentConfig (config );
170209 }
171210
172211 List <String > matchInterfaceList = AsmAnnotationUtils .queryAnnotationArrayValue (classNode .visibleAnnotations ,
173212 Type .getDescriptor (Instrument .class ), "Interface" );
174213
175214 if (!matchInterfaceList .isEmpty ()) {
176215 SimpleInterfaceMatcher matcher = new SimpleInterfaceMatcher (matchInterfaceList );
177- result .addInstrumentConfig (new InstrumentConfig (classNode , matcher , updateMajorVersion , triggerRetransform ));
216+ InstrumentConfig config = new InstrumentConfig (classNode , matcher , updateMajorVersion , triggerRetransform );
217+ addDefineConfigs (config , defineClassList );
218+ result .addInstrumentConfig (config );
178219 }
179220
180221 // TODO 处理 @NewField
181222 }
182223
224+ /**
225+ * 将 define 类列表添加到 InstrumentConfig
226+ */
227+ private void addDefineConfigs (InstrumentConfig config , List <Pair <String , byte []>> defineClassList ) {
228+ if (defineClassList != null && !defineClassList .isEmpty ()) {
229+ for (Pair <String , byte []> pair : defineClassList ) {
230+ config .addDefineConfig (new DefineConfig (pair .second , pair .first ));
231+ }
232+ }
233+ }
234+
183235 public static List <Class <?>> matchedClass (Instrumentation instrumentation , InstrumentConfig instrumentConfig ) {
184236 List <Class <?>> result = new ArrayList <Class <?>>();
185237
0 commit comments