javassist_框架中具体aop实现
/* * Copyright 2004-2010 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */package org.seasar.framework.aop.interceptors;import java.util.Arrays;import java.util.Date;import java.util.LinkedHashSet;import junit.framework.TestCase;import org.seasar.framework.aop.Aspect;import org.seasar.framework.aop.Pointcut;import org.seasar.framework.aop.impl.AspectImpl;import org.seasar.framework.aop.impl.PointcutImpl;import org.seasar.framework.aop.proxy.AopProxy;/** * @author higa * */public class TraceInterceptorTest extends TestCase { /** * @throws Exception */ public void testIntercept() throws Exception { TraceInterceptor interceptor = new TraceInterceptor(); Pointcut pointcut = new PointcutImpl(new String[] { "getTime" }); Aspect aspect = new AspectImpl(interceptor, pointcut); AopProxy aopProxy = new AopProxy(Date.class, new Aspect[] { aspect }); Date proxy = (Date) aopProxy.create(); proxy.getTime(); } /** * @throws Exception * 对它进行操作,看javassist生成的字节码 * */ public void testIntercept2() throws Exception { TraceInterceptor interceptor = new TraceInterceptor(); Pointcut pointcut = new PointcutImpl(new String[] { "hoge" }); Aspect aspect = new AspectImpl(interceptor, pointcut); AopProxy aopProxy = new AopProxy(ThrowError.class, new Aspect[] { aspect }); ThrowError proxy = (ThrowError) aopProxy.create(); try { proxy.hoge(); } catch (Throwable ignore) { } } /** * @throws Exception */ public void testIntercept3() throws Exception { TraceInterceptor interceptor = new TraceInterceptor(); Pointcut pointcut = new PointcutImpl(new String[] { "geho" }); Aspect aspect = new AspectImpl(interceptor, pointcut); AopProxy aopProxy = new AopProxy(ThrowError.class, new Aspect[] { aspect }); ThrowError proxy = (ThrowError) aopProxy.create(); proxy.geho(new String[0]); } /** * @throws Exception */ public void testInterceptArray() throws Exception { TraceInterceptor interceptor = new TraceInterceptor(); Pointcut pointcut = new PointcutImpl(new String[] { "hoge" }); Aspect aspect = new AspectImpl(interceptor, pointcut); AopProxy aopProxy = new AopProxy(ArrayHoge.class, new Aspect[] { aspect }); ArrayHoge proxy = (ArrayHoge) aopProxy.create(); proxy.hoge(new String[] { "111" }); } /** * @throws Exception */ public void testInterceptPrimitiveArray() throws Exception { TraceInterceptor interceptor = new TraceInterceptor(); Pointcut pointcut = new PointcutImpl(new String[] { "hoge" }); Aspect aspect = new AspectImpl(interceptor, pointcut); AopProxy aopProxy = new AopProxy(ArrayHoge.class, new Aspect[] { aspect }); ArrayHoge proxy = (ArrayHoge) aopProxy.create(); proxy.hoge(new int[] { 1, 2 }); } /** * @throws Exception */ public void testAppendObject() throws Exception { TraceInterceptor interceptor = new TraceInterceptor(); assertEquals("null", interceptor.appendObject(new StringBuffer(), null) .toString()); assertEquals("[abc]", interceptor.appendObject(new StringBuffer(), new Object[] { "abc" }).toString()); assertEquals("[abc, [1], [a, b], [A, B, C]]", interceptor.appendObject( new StringBuffer(), new Object[] { "abc", new Object[] { "1" }, Arrays.asList(new Object[] { "a", "b" }), new LinkedHashSet(Arrays.asList(new Object[] { "A", "B", "C" })) }).toString()); } /** * @throws Exception */ public void testAppendArray() throws Exception { TraceInterceptor interceptor = new TraceInterceptor(); assertEquals("[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]", interceptor .appendObject( new StringBuffer(), new Object[] { new Object[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" } }) .toString()); interceptor.setMaxLengthOfCollection(11); assertEquals("[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]]", interceptor .appendObject( new StringBuffer(), new Object[] { new Object[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" } }) .toString()); interceptor.setMaxLengthOfCollection(20); assertEquals("[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]", interceptor .appendObject( new StringBuffer(), new Object[] { new Object[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" } }) .toString()); } /** * @author higa * */ public static class ThrowError { /** * */ public void hoge() { throw new RuntimeException("hoge"); } /** * @param array */ public void geho(String[] array) { } } /** * @author higa * */ public static class ArrayHoge { /** * @param arg * @return */ public String[] hoge(String[] arg) { return new String[] { "aaa", "bbb" }; } /** * @param arg * @return */ public int[] hoge(int[] arg) { return new int[] { 10, 20 }; } }}
修改类
/* * Copyright 2004-2010 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */package org.seasar.framework.aop.javassist;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.security.AccessController;import java.security.PrivilegedAction;import java.security.ProtectionDomain;import javassist.CannotCompileException;import javassist.ClassPool;import javassist.CtClass;import javassist.CtConstructor;import javassist.CtMethod;import javassist.CtNewConstructor;import javassist.CtNewMethod;import javassist.NotFoundException;import javassist.bytecode.analysis.FramePrinter;import org.seasar.framework.exception.CannotCompileRuntimeException;import org.seasar.framework.exception.IORuntimeException;import org.seasar.framework.exception.IllegalAccessRuntimeException;import org.seasar.framework.exception.InvocationTargetRuntimeException;import org.seasar.framework.exception.NoSuchMethodRuntimeException;import org.seasar.framework.exception.NotFoundRuntimeException;import org.seasar.framework.util.ClassPoolUtil;import org.seasar.framework.util.ClassUtil;/** * バイトコドを生成するための抽象クラスです。 * * @author koichik */public class AbstractGenerator { /** * defineClassです。 */ protected static final String DEFINE_CLASS_METHOD_NAME = "defineClass"; /** * 保ドメインです。 */ protected static final ProtectionDomain protectionDomain; /** * defineClassメソッドです。 */ protected static Method defineClassMethod; // static initializer static { protectionDomain = (ProtectionDomain) AccessController .doPrivileged(new PrivilegedAction() { public Object run() { return AspectWeaver.class.getProtectionDomain(); } }); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { final Class[] paramTypes = new Class[] { String.class, byte[].class, int.class, int.class, ProtectionDomain.class }; try { final Class loader = ClassUtil.forName(ClassLoader.class .getName()); defineClassMethod = loader.getDeclaredMethod( DEFINE_CLASS_METHOD_NAME, paramTypes); defineClassMethod.setAccessible(true); } catch (final NoSuchMethodException e) { throw new NoSuchMethodRuntimeException(ClassLoader.class, DEFINE_CLASS_METHOD_NAME, paramTypes, e); } return null; } }); } /** * クラスプルです。 * @uml.property name="classPool" * @uml.associationEnd multiplicity="(1 1)" */ protected final ClassPool classPool; /** * オブジェクトの表から文字列表にします。 * * @param type * 型 * @param expr * * @return 文字列表 */ protected static String fromObject(final Class type, final String expr) { if (type.equals(void.class) || type.equals(Object.class)) { return expr; } if (type.equals(boolean.class) || type.equals(char.class)) { final Class wrapper = ClassUtil.getWrapperClass(type); return "((" + wrapper.getName() + ") " + expr + ")." + type.getName() + "Value()"; } if (type.isPrimitive()) { return "((java.lang.Number) " + expr + ")." + type.getName() + "Value()"; } return "(" + ClassUtil.getSimpleClassName(type) + ") " + expr; } /** * オブジェクトの文字列表にします。 * * @param type * 型 * @param expr * * @return 文字列表 */ protected static String toObject(final Class type, final String expr) { if (type.isPrimitive()) { final Class wrapper = ClassUtil.getWrapperClass(type); return "new " + wrapper.getName() + "(" + expr + ")"; } return expr; } /** * {@link AbstractGenerator}を作成します。 * * @param classPool * クラスプル */ protected AbstractGenerator(final ClassPool classPool) { this.classPool = classPool; } /** * コンパイルのクラスにします。 * * @param clazz * 元のクラス * @return コンパイルのクラス */ protected CtClass toCtClass(final Class clazz) { return ClassPoolUtil.toCtClass(classPool, clazz); } /** * コンパイルのクラスにします。 * * @param className * クラス名 * @return コンパイルのクラス */ protected CtClass toCtClass(final String className) { return ClassPoolUtil.toCtClass(classPool, className); } /** * コンパイルのクラスの配列にします。 * * @param classNames * 元のクラス名の配列 * @return コンパイルのクラスの配列 */ protected CtClass[] toCtClassArray(final String[] classNames) { return ClassPoolUtil.toCtClassArray(classPool, classNames); } /** * コンパイルのクラスの配列にします。 * * @param classes * 元のクラスの配列 * @return コンパイルのクラスの配列 */ protected CtClass[] toCtClassArray(final Class[] classes) { return ClassPoolUtil.toCtClassArray(classPool, classes); } /** * コンパイルのクラスを作成します。 * * @param name * クラス名 * @return コンパイルのクラス */ protected CtClass createCtClass(final String name) { return ClassPoolUtil.createCtClass(classPool, name); } /** * コンパイルのクラスを作成します。 * * @param name * クラス名 * @param superClass * クラス * @return コンパイルのクラス */ protected CtClass createCtClass(final String name, final Class superClass) { return ClassPoolUtil.createCtClass(classPool, name, superClass); } /** * コンパイルのクラスを作成します。 * * @param name * クラス名 * @param superClass * クラス * @return コンパイルのクラス */ protected CtClass createCtClass(final String name, final CtClass superClass) { return ClassPoolUtil.createCtClass(classPool, name, superClass); } /** * コンパイルのクラスを取得して名前をえます。 * * @param orgClass * 元のクラス * @param newName * 新しい名前 * @return コンパイルのクラス */ protected CtClass getAndRenameCtClass(final Class orgClass, final String newName) { return getAndRenameCtClass(ClassUtil.getSimpleClassName(orgClass), newName); } /** * コンパイルのクラスを取得して名前をえます。 * * @param orgName * 元の名前 * @param newName * 新しい名前 * @return コンパイルのクラス */ protected CtClass getAndRenameCtClass(final String orgName, final String newName) { try { return classPool.getAndRename(orgName, newName); } catch (final NotFoundException e) { throw new NotFoundRuntimeException(e); } } /** * <code>CtClass</code>を<code>Class</code>に更します。 * * @param classLoader * クラスロダ * @param ctClass * コンパイルのクラス * @return クラス */ public Class toClass(final ClassLoader classLoader, final CtClass ctClass) { try {//这里 ctClass.writeFile("D:/javassist_class"); final byte[] bytecode = ctClass.toBytecode(); // 使用可选的 ProtectionDomain 将一个 byte 数组转换为 Class 类的实例。如果该域为 null,则将默认域分配给 defineClass(String, byte[], int, int) 的文档中指定的类。这个类必须分析后才能使用。 // 包中定义的第一个类确定在该包中定义的所有后续类必须包含的证书的确切集合。从该类的 ProtectionDomain 中的 CodeSource 可以获得类的证书集合。添加到该包中的任何类都必须包含相同的证书集合,否则抛出 SecurityException 异常。注意,如果 name 为 null,则不执行该检查。应该始终传入要定义的类的二进制名称以及字节。这可确保定义该类的正确性。 // 指定的 name 不能以 "java." 开头,因为 "java.*" 包中的所有类都只能由引导类加载器定义。如果 name 不是 null,则它必定等于由 byte 数组 "b" 指定的类的二进制名称,否则将抛出 NoClassDefFoundError。 return (Class) defineClassMethod.invoke(classLoader, new Object[] { ctClass.getName(), bytecode, new Integer(0), new Integer(bytecode.length), protectionDomain }); } catch (final CannotCompileException e) { throw new CannotCompileRuntimeException(e); } catch (final IOException e) { throw new IORuntimeException(e); } catch (final IllegalAccessException e) { throw new IllegalAccessRuntimeException(ClassLoader.class, e); } catch (final InvocationTargetException e) { throw new InvocationTargetRuntimeException(ClassLoader.class, e); } } /** * インタフェスを定します。 * * @param clazz * 象のコンパイルクラス * @param interfaceType * インタフェス */ protected void setInterface(final CtClass clazz, final Class interfaceType) { clazz.setInterfaces(new CtClass[] { toCtClass(interfaceType) }); } /** * インタフェスの配列を定します。 * * @param clazz * 象のコンパイルクラス * @param interfaces * インタフェスの配列 */ protected void setInterfaces(final CtClass clazz, final Class[] interfaces) { clazz.setInterfaces(toCtClassArray(interfaces)); } /** * デフォルトコンストラクタを作成します。 * * @param clazz * 元のクラス * @return コンパイルコンストラクタ */ protected CtConstructor createDefaultConstructor(final Class clazz) { return createDefaultConstructor(toCtClass(clazz)); } /** * デフォルトコンストラクタを作成します。 * * @param clazz * 象のコンパイルクラス * @return コンパイルコンストラクタ */ protected CtConstructor createDefaultConstructor(final CtClass clazz) { try { final CtConstructor ctConstructor = CtNewConstructor .defaultConstructor(clazz); clazz.addConstructor(ctConstructor); return ctConstructor; } catch (final CannotCompileException e) { throw new CannotCompileRuntimeException(e); } } /** * コンストラクタを作成します。 * * @param clazz * 象となるコンパイルクラス * @param constructor * 元のコンストラクタ * @return コンパイルコンストラクタ */ protected CtConstructor createConstructor(final CtClass clazz, final Constructor constructor) { return createConstructor(clazz, toCtClassArray(constructor .getParameterTypes()), toCtClassArray(constructor .getExceptionTypes())); } /** * コンストラクタを作成します。 * * @param clazz * 象となるコンパイルクラス * @param parameterTypes * パラメタの型の配列 * @param exceptionTypes * 例外の型の配列 * @return コンパイルコンストラクタ */ protected CtConstructor createConstructor(final CtClass clazz, final CtClass[] parameterTypes, final CtClass[] exceptionTypes) { try { final CtConstructor ctConstructor = CtNewConstructor.make( parameterTypes, exceptionTypes, clazz); clazz.addConstructor(ctConstructor); return ctConstructor; } catch (final CannotCompileException e) { throw new CannotCompileRuntimeException(e); } } /** * 宣言されているメソッドを返します。 * * @param clazz * 象のコンパイルクラス * @param name * メソッド名 * @param argTypes * パラメタの型の配列 * @return コンパイルメソッド */ protected CtMethod getDeclaredMethod(final CtClass clazz, final String name, final CtClass[] argTypes) { try { return clazz.getDeclaredMethod(name, argTypes); } catch (final NotFoundException e) { throw new NotFoundRuntimeException(e); } } /** * メソッドを作成します。 * * @param clazz * 象のコンパイルクラス * @param src * ソス * @return コンパイルメソッド */ protected CtMethod createMethod(final CtClass clazz, final String src) { try { final CtMethod ctMethod = CtNewMethod.make(src, clazz); clazz.addMethod(ctMethod); return ctMethod; } catch (final CannotCompileException e) { throw new CannotCompileRuntimeException(e); } } /** * メソッドを作成します。 * * @param clazz * 象のコンパイルクラス * @param method * 元のメソッド * @param body * メソッドの中身 * @return コンパイルメソッド */ protected CtMethod createMethod(final CtClass clazz, final Method method, final String body) { return createMethod(clazz, method.getModifiers(), method .getReturnType(), method.getName(), method.getParameterTypes(), method.getExceptionTypes(), body); } /** * メソッドを作成します。 * * @param clazz * 象となるコンパイルクラス * @param modifier * アクセス修子 * @param returnType * りの型 * @param methodName * メソッド名 * @param parameterTypes * パラメタの型の配列 * @param exceptionTypes * 例外の型の配列 * @param body * メソッドの中身 * @return コンパイルメソッド * * * * */ protected CtMethod createMethod(final CtClass clazz, final int modifier, final Class returnType, final String methodName, final Class[] parameterTypes, final Class[] exceptionTypes, final String body) { try { final CtMethod ctMethod = CtNewMethod.make(modifier & ~(Modifier.ABSTRACT | Modifier.NATIVE), toCtClass(returnType), methodName, toCtClassArray(parameterTypes), toCtClassArray(exceptionTypes), body, clazz); clazz.addMethod(ctMethod); FramePrinter.print(clazz, System.out); return ctMethod; } catch (final CannotCompileException e) { throw new CannotCompileRuntimeException(e); } } /** * メソッドの中身を定します。 * * @param method * コンパイルメソッド * @param src * ソス */ protected void setMethodBody(final CtMethod method, final String src) { try { method.setBody(src); } catch (final CannotCompileException e) { throw new CannotCompileRuntimeException(e); } }}
生成结果
TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9.class
TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.class
javap查看字节码:
Compiled from "TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9.java"public class org.seasar.framework.aop.interceptors.TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9 extends org.seasar.framework.aop.interceptors.TraceInterceptorTest$ThrowError SourceFile: "TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9.java" minor version: 0 major version: 49 Constant pool:const #1 = Ascizorg/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9;const #2 = class#1;// org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9const #3 = Ascizorg/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError;const #4 = class#3;// org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowErrorconst #5 = Asciz<init>;const #6 = Asciz()V;const #7 = AscizCode;const #8 = class#3;// org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowErrorconst #9 = NameAndType#5:#6;// "<init>":()Vconst #10 = Method#8.#9;// org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError."<init>":()Vconst #11 = Asciz$$hoge$$invokeSuperMethod$$;const #12 = Ascizhoge;const #13 = NameAndType#12:#6;// hoge:()Vconst #14 = Method#8.#13;// org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError.hoge:()Vconst #15 = Ascizjava/lang/RuntimeException;const #16 = class#15;// java/lang/RuntimeExceptionconst #17 = Ascizjava/lang/Error;const #18 = class#17;// java/lang/Errorconst #19 = Ascizjava/lang/Throwable;const #20 = class#19;// java/lang/Throwableconst #21 = Ascizorg/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0;const #22 = class#21;// org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0const #23 = Ascizjava/lang/Object;const #24 = class#23;// java/lang/Objectconst #25 = Asciz(Ljava/lang/Object;[Ljava/lang/Object;)V;const #26 = NameAndType#5:#25;// "<init>":(Ljava/lang/Object;[Ljava/lang/Object;)Vconst #27 = Method#22.#26;// org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0."<init>":(Ljava/lang/Object;[Ljava/lang/Object;)Vconst #28 = Ascizproceed;const #29 = Asciz()Ljava/lang/Object;;const #30 = NameAndType#28:#29;// proceed:()Ljava/lang/Object;const #31 = Method#22.#30;// org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.proceed:()Ljava/lang/Object;const #32 = Ascizjava/lang/reflect/UndeclaredThrowableException;const #33 = class#32;// java/lang/reflect/UndeclaredThrowableExceptionconst #34 = Asciz(Ljava/lang/Throwable;)V;const #35 = NameAndType#5:#34;// "<init>":(Ljava/lang/Throwable;)Vconst #36 = Method#33.#35;// java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)Vconst #37 = AscizSourceFile;const #38 = AscizTraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9.java;{public org.seasar.framework.aop.interceptors.TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9(); Code: Stack=1, Locals=1, Args_size=1 0:aload_0 1:invokespecial#10; //Method org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError."<init>":()V 4:returnpublic void $$hoge$$invokeSuperMethod$$(); Code: Stack=1, Locals=1, Args_size=1 0:aload_0 //己经很明显了,不用说明了 1:invokespecial#14; //Method org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError.hoge:()V 4:aconst_null 5:pop 6:returnpublic void hoge(); Code: Stack=4, Locals=3, Args_size=1 0:new#22; //class org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0 3:dup 4:aload_0 5:iconst_0 6:anewarray#24; //class java/lang/Object 9:invokespecial#27; //Method org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0."<init>":(Ljava/lang/Object;[Ljava/lang/Object;)V 这里是入口 12:invokevirtual#31; //Method org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.proceed:()Ljava/lang/Object; 15:astore_1 16:return 17:astore_2 18:aload_2 19:athrow 20:astore_2 21:aload_2 22:athrow 23:astore_2 24:new#33; //class java/lang/reflect/UndeclaredThrowableException 27:dup 28:aload_2 29:invokespecial#36; //Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V 32:athrow Exception table: from to target type 0 17 17 Class java/lang/RuntimeException 0 17 20 Class java/lang/Error 0 17 23 Class java/lang/Throwable}Compiled from "MethodInvocationClassGenerator.java"public class org.seasar.framework.aop.interceptors.TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0 extends java.lang.Object implements org.seasar.framework.aop.S2MethodInvocation{private static java.lang.Class targetClass;private static java.lang.reflect.Method method;static org.aopalliance.intercept.MethodInterceptor[] interceptors;private static java.util.Map parameters;private java.lang.Object target;private java.lang.Object[] arguments;int interceptorsIndex;public org.seasar.framework.aop.interceptors.TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0(java.lang.Object, java.lang.Object[]); Code: 0:aload_0 1:invokespecial#21; //Method java/lang/Object."<init>":()V 4:aload_0 5:aload_1 6:putfield#24; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.target:Ljava/lang/Object; 9:aload_0 10:aload_2 11:putfield#26; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.arguments:[Ljava/lang/Object; 14:returnpublic java.lang.Class getTargetClass(); Code: 0:getstatic#32; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.targetClass:Ljava/lang/Class; 3:areturnpublic java.lang.reflect.Method getMethod(); Code: 0:getstatic#38; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.method:Ljava/lang/reflect/Method; 3:areturnpublic java.lang.reflect.AccessibleObject getStaticPart(); Code: 0:getstatic#42; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.method:Ljava/lang/reflect/Method; 3:areturnpublic java.lang.Object getParameter(java.lang.String); Code: 0:getstatic#50; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.parameters:Ljava/util/Map; 3:ifnonnull8 6:aconst_null 7:areturn 8:getstatic#52; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.parameters:Ljava/util/Map; 11:aload_1 12:invokeinterface#58, 2; //InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object; 17:areturnpublic java.lang.Object getThis(); Code: 0:aload_0 1:getfield#62; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.target:Ljava/lang/Object; 4:areturnpublic java.lang.Object[] getArguments(); Code: 0:aload_0 1:getfield#66; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.arguments:[Ljava/lang/Object; 4:areturnpublic java.lang.Object proceed() throws java.lang.Throwable; Code: 0:aload_0 1:getfield#74; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.interceptorsIndex:I 4:getstatic#78; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.interceptors:[Lorg/aopalliance/intercept/MethodInterceptor; 7:arraylength 8:if_icmpge33 11:getstatic#80; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.interceptors:[Lorg/aopalliance/intercept/MethodInterceptor; 14:aload_0 15:dup 16:getfield#82; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.interceptorsIndex:I 19:dup_x1 20:iconst_1 21:iadd 22:putfield#84; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.interceptorsIndex:I 25:aaload 26:aload_0 27:invokeinterface#90, 2; //InterfaceMethod org/aopalliance/intercept/MethodInterceptor.invoke:(Lorg/aopalliance/intercept/MethodInvocation;)Ljava/lang/Object; 32:areturn 33:aload_0 34:getfield#92; //Field org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9$$MethodInvocation$$hoge0.target:Ljava/lang/Object; 37:checkcast#94; //class org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9 //这里是对原来的方法的调用 40:invokevirtual#97; //Method org/seasar/framework/aop/interceptors/TraceInterceptorTest$ThrowError$$EnhancedByS2AOP$$192c8d9.$$hoge$$invokeSuperMethod$$:()V 43:aconst_null 44:areturn}