@Test public void test() throws Exception { DefaultInterceptorClassParser defaultInterceptorClassParser = new DefaultInterceptorClassParser(); List<InterceptorProcessor> interceptorProcessors = defaultInterceptorClassParser.parse(SpyInterceptor.class); ClassNode classNode = AsmUtils.loadClass(TestAAA.class); List<MethodNode> matchedMethods = new ArrayList<MethodNode>(); for (MethodNode methodNode : classNode.methods) { if (MatchUtils.wildcardMatch(methodNode.name, "*")) { matchedMethods.add(methodNode); } } LocationFilter enterFilter = new InvokeContainLocationFilter(Type.getInternalName(SpyAPI.class), "atEnter", LocationType.ENTER); LocationFilter existFilter = new InvokeContainLocationFilter(Type.getInternalName(SpyAPI.class), "atExit", LocationType.EXIT); LocationFilter exceptionFilter = new InvokeContainLocationFilter(Type.getInternalName(SpyAPI.class), "atExceptionExit", LocationType.EXCEPTION_EXIT); GroupLocationFilter groupLocationFilter = new GroupLocationFilter(); groupLocationFilter.addFilter(enterFilter); groupLocationFilter.addFilter(existFilter); groupLocationFilter.addFilter(exceptionFilter); for (MethodNode methodNode : matchedMethods) { MethodProcessor methodProcessor = new MethodProcessor(classNode, methodNode, groupLocationFilter); for (InterceptorProcessor interceptor : interceptorProcessors) { interceptor.process(methodProcessor); } } for (MethodNode methodNode : matchedMethods) { MethodProcessor methodProcessor = new MethodProcessor(classNode, methodNode, groupLocationFilter); for (InterceptorProcessor interceptor : interceptorProcessors) { interceptor.process(methodProcessor); } } for (MethodNode methodNode : matchedMethods) { MethodProcessor methodProcessor = new MethodProcessor(classNode, methodNode, groupLocationFilter); for (InterceptorProcessor interceptor : interceptorProcessors) { interceptor.process(methodProcessor); } } byte[] bytes = AsmUtils.toBytes(classNode); VerifyUtils.asmVerify(bytes); System.out.println(Decompiler.decompile(bytes)); ClassNode classNode2 = AsmUtils.toClassNode(bytes); for (MethodNode methodNode : classNode2.methods) { System.err.println("method name: " + methodNode.name); Assertions .assertThat(AsmUtils.findMethodInsnNode(methodNode, Type.getInternalName(SpyAPI.class), "atEnter")) .size().isEqualTo(1); Assertions .assertThat(AsmUtils.findMethodInsnNode(methodNode, Type.getInternalName(SpyAPI.class), "atExit")) .size().isEqualTo(1); Assertions .assertThat(AsmUtils.findMethodInsnNode(methodNode, Type.getInternalName(SpyAPI.class), "atExceptionExit")) .size().isEqualTo(1); } }
private MethodInsnNode findMethodInsnNode(AbstractInsnNode insnNode) { AbstractInsnNode current = insnNode; while (current != null) { current = current.getNext(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } current = insnNode; while (current != null) { current = current.getPrevious(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } return null; }
InvokeContainLocationFilter implements LocationFilter { private MethodInsnNode findMethodInsnNode(AbstractInsnNode insnNode) { AbstractInsnNode current = insnNode; while (current != null) { current = current.getNext(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } current = insnNode; while (current != null) { current = current.getPrevious(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } return null; } }
InvokeContainLocationFilter implements LocationFilter { private MethodInsnNode findMethodInsnNode(AbstractInsnNode insnNode) { AbstractInsnNode current = insnNode; while (current != null) { current = current.getNext(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } current = insnNode; while (current != null) { current = current.getPrevious(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } return null; } InvokeContainLocationFilter(String owner, String methodName, LocationType locationType); }
InvokeContainLocationFilter implements LocationFilter { private MethodInsnNode findMethodInsnNode(AbstractInsnNode insnNode) { AbstractInsnNode current = insnNode; while (current != null) { current = current.getNext(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } current = insnNode; while (current != null) { current = current.getPrevious(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } return null; } InvokeContainLocationFilter(String owner, String methodName, LocationType locationType); @Override boolean allow(AbstractInsnNode insnNode, LocationType locationType, boolean complete); }
InvokeContainLocationFilter implements LocationFilter { private MethodInsnNode findMethodInsnNode(AbstractInsnNode insnNode) { AbstractInsnNode current = insnNode; while (current != null) { current = current.getNext(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } current = insnNode; while (current != null) { current = current.getPrevious(); if (current instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) current; if (methodInsnNode.owner.equals(this.owner) && methodInsnNode.name.equals(this.methodName)) { return methodInsnNode; } } } return null; } InvokeContainLocationFilter(String owner, String methodName, LocationType locationType); @Override boolean allow(AbstractInsnNode insnNode, LocationType locationType, boolean complete);  }