动态代理、CGLIB 与 切面编程
跳到导航
跳到搜索
关于代理
代理,简单说就是:不直接操作对象,而使用代理对象来完成操作。 通过代理对象,可以对原对象进行方法扩展。
代理又可以分为:
- 静态代理:通过聚合、继承的方式生成代理对象;
- 代理关系在编译时就确定了
- 动态代理:
- 运行期动态生成代理对象;
- Java动态代理:
- 只能够对接口(目标类必须实现接口)进行代理 —— 因为所有生成的代理类的父类为 Proxy,而 Java 类继承机制不允许多重继承;
- 类的生成过程更高效 —— 使用 Java 原生的反射 API 进行操作;
- “代理类”为 Proxy 的子类;
- CGLIB:
- 能够对普通类(没有实现接口的类)进行代理;
- 类的执行过程更高效 —— 使用 ASM 框架直接对字节码进行操作;
- “代理类”为“目标类”的子类;
- AspectJ:(SpringFramework 的 AOP 基于此实现)。
Java动态代理
示例
Java中动态代理的实现,关键在于:“Proxy”、“InvocationHandler”的关联。 注意:invoke 方法的自动调用。
以实例分析:
- 抽象接口:
//抽象角色(动态代理只能代理接口) public interface Subject { public void request(); }
- 抽象接口实现:
//真实角色:实现了Subject的request()方法 public class RealSubject implements Subject{ public void request(){ System.out.println("From real subject."); } }
- “InvocationHandler”接口的实现类:
//实现了InvocationHandler public class DynamicSubject implements InvocationHandler { private Object obj;//这是动态代理的好处,被封装的对象是Object类型,接受任意类型的对象 public DynamicSubject() { } public DynamicSubject(Object obj) { this.obj = obj; } //这个方法不是我们显示的去调用 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling " + method); method.invoke(obj, args); System.out.println("after calling " + method); return null; } }
- “invoke”方法进行代理处理逻辑,并调用对应的接口方法;
- 使用“method.invoke(obj, args);”,而不能使用“method.invoke(proxy, args); ”(后者将会导致死循环);
- “obj”:类型为“RealSubject”(由下面测试类中,初始化“DynamicSubject”的参数而来):
- “proxy”:就是代理实例“$Proxy0”:
- “method.invoke(proxy, args);”将会调用“$Proxy0”的method方法;
- 而“$Proxy0”的method方法,会执行“super.h.invoke(this, m3, null);”,即调用此处,从而调用陷入死循环;
- 测试类:
//客户端:生成代理实例,并调用了request()方法 public class Client { public static void main(String[] args) throws Throwable{ Subject rs = new RealSubject();//这里指定被代理类 InvocationHandler ds = new DynamicSubject(rs); Class<?> cls = rs.getClass(); //以下是一次性生成代理 Subject subject=(Subject) Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(), ds); //这里可以看出subject的Class类是$Proxy0,这个$Proxy0类继承了Proxy,实现了Subject接口 System.out.println("subject的Class类是:"+subject.getClass().toString()); System.out.println("subject的父类是:"+subject.getClass().getSuperclass()); System.out.print("\n"+"subject实现的接口是:"); Class<?>[] interfaces=subject.getClass().getInterfaces(); for(Class<?> i:interfaces){ System.out.print(i.getName()+", "); } System.out.print("\n"+"subject中的属性有:"); Field[] field=subject.getClass().getDeclaredFields(); for(Field f:field){ System.out.print(f.getName()+", "); } System.out.print("\n"+"subject中的方法有:"); Method[] method=subject.getClass().getDeclaredMethods(); for(Method m:method){ System.out.print(m.getName()+", "); } System.out.println("\n\n"+"运行结果为:"); subject.request(); } }
- 运行结果如下:
subject的Class类是:class com.sun.proxy.$Proxy0 subject的父类是:class java.lang.reflect.Proxy subject实现的接口是:Test1.Subject, subject中的属性有:m1, m2, m3, m0, subject中的方法有:equals, toString, hashCode, request, 运行结果为: before calling public abstract void Test1.Subject.request() From real subject. after calling public abstract void Test1.Subject.request()
- 如果初始化“DynamicSubject”时,传入参数不是“RealSubject”类型,则,DynamicSubject中的“method.invoke(obj, args); ”将不能执行:
- 错误信息:“object is not an instance of declaring class”
代码分析
- “Proxy”的部分源码:
class Proxy{ InvocationHandler h=null; protected Proxy(InvocationHandler h) { this.h = h; } ... public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) }
- Proxy 会生成一个“由loader加载”、“继承于Proxy”、“实现了interfaces等接口”的代理类“$Proxy0”;
- Proxy 会将“InvocationHandler”实例保存在属性中;
- 生成的“$Proxy0”:
public final class $Proxy0 extends Proxy implements Subject { private static Method m1; private static Method m0; private static Method m3; private static Method m2; static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("***.RealSubject").getMethod("request", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch (ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } //static public $Proxy0(InvocationHandler invocationhandler) { super(invocationhandler); } @Override public final boolean equals(Object obj) { try { return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final void request() { try { super.h.invoke(this, m3, null); return; } catch (Error e) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final String toString() { try { return (String) super.h.invoke(this, m2, null); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } }
- 其中“m1”、“m0”、“m3”、“m2”是“Method”类型的字段,表示“$Proxy0”中方法所对应的原方法;包括:
- 继承于“Object”的“equals”(m1)、“hashCode”(m0)、“toString”(m2)
- 实现“Subject”的“request”(m3);
- “$Proxy0”的方法实现:“super.h.invoke(this, m3, null);”:
- 调用父类的“h”(“InvocationHandler”实例)的“invoke”方法;(“invoke”中进行代理处置,并调用原始方法)
- 参数:“this”($Proxy0)、“m2”(原始方法)、“null”(方法参数)
AspectJ
- 参见:Spring:AOP
CGLIB
CGLIB(Code Generation Library),是一个功能强大,高性能的代码生成包。
- 使用CGLib实现动态代理,完全不受“被代理类必须实现接口”的限制;
- CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。
原理
- 动态生成一个目标类的子类,子类重写目标类的“所有非 Final”的方法。
- 在子类中采用方法拦截的技术,拦截所有父类方法的调用,并织入横切逻辑。
- 为没有实现接口的类提供代理,比于“JDK 动态代理”(只能代理接口)更加强大;
- 不能代理 Final 方法;
CGLIB组成结构
CGLIB 底层使用了ASM(一个短小精悍的字节码操作框架)来操作字节码生成新的类。
- 因为使用字节码技术生成代理类,所以 CGLIB 比采用“Java反射”的“JDK 动态代理”更快;
- 关于“ASM”:
- 除了CGLIB库外,脚本语言(如:“Groovy”、“BeanShell”)也使用ASM生成字节码;
- ASM使用类似SAX的解析器来实现高性能;
- (如果直接使用ASM,需要对Java字节码非常了解)
jar包
- “cglib-nodep-2.2.jar”:使用nodep包不需要关联asm的jar包,jar包内部包含asm的类.
- “cglib-2.2.jar”:使用此jar包需要关联asm的jar包,否则运行时报错.
类库
CGLIB 类库:
- “net.sf.cglib.core”:底层字节码处理类,他们大部分与ASM有关系;
- “net.sf.cglib.transform”:编译期或运行期类和类文件的转换;
- “net.sf.cglib.proxy”:实现创建代理和方法拦截器的类;
- “net.sf.cglib.reflect”:实现快速反射和C#风格代理的类;
- “net.sf.cglib.util”:集合排序等工具类;
- “net.sf.cglib.beans”:JavaBean相关的工具类;
常用的API
见:CGLIB(Code Generation Library)详解
命令 | 说明 | 示例 |
---|---|---|
Enhancer | Enhancer创建一个被代理对象的子类并且拦截所有的方法调用(包括从Object中继承的toString和hashCode方法)
|
public class SampleClass {
public void test(){
System.out.println("hello world");
}
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SampleClass.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before method run...");
Object result = proxy.invokeSuper(obj, args);
System.out.println("after method run...");
return result;
}
});
SampleClass sample = (SampleClass) enhancer.create();
sample.test();
}
}
输出: before method run...
hello world
after method run...
|
ImmutableBean | 不可变的Bean
|
public class SampleBean {
private String value;
public SampleBean() {
}
public SampleBean(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@Test(expected = IllegalStateException.class)
public void testImmutableBean() throws Exception{
SampleBean bean = new SampleBean();
bean.setValue("Hello world");
SampleBean immutableBean = (SampleBean) ImmutableBean.create(bean); //创建不可变类
Assert.assertEquals("Hello world",immutableBean.getValue());
bean.setValue("Hello world, again"); //可以通过底层对象来进行修改
Assert.assertEquals("Hello world, again", immutableBean.getValue());
immutableBean.setValue("Hello cglib"); //直接修改将throw exception
}
|
Bean generator | cglib提供的一个操作bean的工具,使用它能够在运行时动态的创建一个bean。 |
@Test
public void testBeanGenerator() throws Exception{
BeanGenerator beanGenerator = new BeanGenerator();
beanGenerator.addProperty("value",String.class);
Object myBean = beanGenerator.create();
Method setter = myBean.getClass().getMethod("setValue",String.class);
setter.invoke(myBean,"Hello cglib");
Method getter = myBean.getClass().getMethod("getValue");
Assert.assertEquals("Hello cglib",getter.invoke(myBean));
}
|
Bean Copier | cglib提供的能够从一个bean复制到另一个bean中,而且其还提供了一个转换器,用来在转换的时候对bean的属性进行操作。 |
public class OtherSampleBean {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
@Test
public void testBeanCopier() throws Exception{
BeanCopier copier = BeanCopier.create(SampleBean.class, OtherSampleBean.class, false);//设置为true,则使用converter
SampleBean myBean = new SampleBean();
myBean.setValue("Hello cglib");
OtherSampleBean otherBean = new OtherSampleBean();
copier.copy(myBean, otherBean, null); //设置为true,则传入converter指明怎么进行转换
assertEquals("Hello cglib", otherBean.getValue());
}
|
BulkBean | 复制bean,BulkBean将copy的动作拆分为getPropertyValues和setPropertyValues两个方法,允许自定义处理属性;
|
@Test
public void testBulkBean() throws Exception{
BulkBean bulkBean = BulkBean.create(SampleBean.class,
new String[]{"getValue"},
new String[]{"setValue"},
new Class[]{String.class});
SampleBean bean = new SampleBean();
bean.setValue("Hello world");
Object[] propertyValues = bulkBean.getPropertyValues(bean);
assertEquals(1, bulkBean.getPropertyValues(bean).length);
assertEquals("Hello world", bulkBean.getPropertyValues(bean)[0]);
bulkBean.setPropertyValues(bean,new Object[]{"Hello cglib"});
assertEquals("Hello cglib", bean.getValue());
}
|
BeanMap | BeanMap类实现了Java Map,将一个bean对象中的所有属性转换为一个String-to-Obejct的Java Map |
@Test
public void testBeanMap() throws Exception{
BeanGenerator generator = new BeanGenerator();
generator.addProperty("username",String.class);
generator.addProperty("password",String.class);
Object bean = generator.create();
Metod setUserName = bean.getClass().getMethod("setUsername", String.class);
Method setPassword = bean.getClass().getMethod("setPassword", String.class);
setUserName.invoke(bean, "admin");
setPassword.invoke(bean,"password");
BeanMap map = BeanMap.create(bean);
Assert.assertEquals("admin", map.get("username"));
Assert.assertEquals("password", map.get("password"));
}
|
keyFactory | eyFactory类用来动态生成接口的实例,接口需要只包含一个newInstance方法,返回一个Object。keyFactory为构造出来的实例动态生成了Object.equals和Object.hashCode方法,能够确保相同的参数构造出的实例为单例的。 | |
Parallel Sorter | (并行排序器) | |
FastClass | 对Class对象进行特定的处理,比如通过数组保存method引用,因此FastClass引出了一个index下标的新概念,比如getIndex(String name, Class[] parameterTypes)就是以前的获取method的方法。
|
@Test
public void testFastClass() throws Exception{
FastClass fastClass = FastClass.create(SampleBean.class);
FastMethod fastMethod = fastClass.getMethod("getValue",new Class[0]);
SampleBean bean = new SampleBean();
bean.setValue("Hello world");
assertEquals("Hello world",fastMethod.invoke(bean, new Object[0]));
}
|
使用
- 被代理类:(没有接口实现)
public class TargetObject { public String method1(String paramName) { return paramName; } public int method2(int count) { return count; } public int method3(int count) { return count; } @Override public String toString() { return "TargetObject []"+ getClass(); } }
- 拦截器:
- (类似于JDK中的“InvocationHandler”接口。)
- 在调用目标方法时,CGLib会回调“MethodInterceptor”接口方法拦截,来实现代理逻辑;
import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class TargetInterceptor implements MethodInterceptor{ /** * 重写方法拦截在方法前和方法后加入业务 * Object obj为目标对象 * Method method为目标方法 * Object[] params 为参数, * MethodProxy proxy CGlib方法代理对象 */ @Override public Object intercept(Object obj, Method method, Object[] params, MethodProxy proxy) throws Throwable { System.out.println("调用前"); Object result = proxy.invokeSuper(obj, params); System.out.println(" 调用后"+result); return result; } }
- 【与“InvocationHandler”接口的“invoke”方法有点类似】
- “obj”:生成的代理实例;
- “method”:被代理类(即,TargetObject)的方法;
- “params”:方法参数;
- “proxy”:生成的代理实例的方法;
- “proxy.invokeSuper(obj, params);”:调用代理类方法所对应的,父类(即,被代理类)的方法;
- 生成动态代理类:
import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.NoOp; public class TestCglib { public static void main(String args[]) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(TargetObject.class); enhancer.setCallback(new TargetInterceptor()); TargetObject targetObject2=(TargetObject)enhancer.create(); System.out.println(targetObject2); System.out.println(targetObject2.method1("mmm1")); System.out.println(targetObject2.method2(100)); System.out.println(targetObject2.method3(200)); } }
- Enhancer类是CGLib中的一个字节码增强器,用于对类的扩展处理;步骤为:
- 创建 Enhancer 对象;
- 设置父类(被代理类);
- 设置回调方法(拦截器);
- 使用 Enhancer 对象,生成代理类;
回调过滤器 CallbackFilter
“JDK 动态代理”中,InvocationHandler 接口方法的调用对代理类内的所以方法都有效;不能针对单个方法实现代理逻辑。
在 CGLib 回调时可以设置对不同方法执行不同的回调逻辑,或者根本不执行回调:
1、添加多个不同的 Callback。
2、设置 CallbackFilter。
【Callback 可以是:“不同的 MethodInterceptor 实现”(不同的拦截器)、“NoOp”(不代理)、“FixedValue”(方法返固定值)】
示例:
- 设置回调过滤器(实现“CallbackFilter”接口):
import java.lang.reflect.Method; import net.sf.cglib.proxy.CallbackFilter; public class TargetMethodCallbackFilter implements CallbackFilter { /** * 过滤方法 * 返回的值为数字,代表了Callback数组中的索引位置,要到用的Callback */ @Override public int accept(Method method) { if(method.getName().equals("method1")){ System.out.println("filter method1 ==0"); return 0; } if(method.getName().equals("method2")){ System.out.println("filter method2 ==1"); return 1; } if(method.getName().equals("method3")){ System.out.println("filter method3 ==2"); return 2; } return 0; } }
- 其中 return 值:为目标类的各个方法在回调数组“Callback[]”中的位置索引(使用哪一个回调函数);
- 如上:method1 将使用下面 Callback[] 中的“callback1”,method2 将使用下面 Callback[] 中的“noopCb”,method3 将使用下面 Callback[] 中的“fixedValue”。
- 锁定方法返回值(实现“FixedValue”接口):
import net.sf.cglib.proxy.FixedValue; /** * 表示锁定方法返回值,无论被代理类的方法返回什么值,回调方法都返回固定值。 * @author zghw * */ public class TargetResultFixed implements FixedValue{ /** * 该类实现FixedValue接口,同时锁定回调值为999 * (整型,CallbackFilter 中定义的使用 FixedValue 型回调的方法为 getConcreteMethodFixedValue,该方法返回值为整型)。 */ @Override public Object loadObject() throws Exception { System.out.println("锁定结果"); Object obj = 999; return obj; } }
- 使用过滤:
import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.NoOp; public class TestCglib { public static void main(String args[]) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(TargetObject.class); CallbackFilter callbackFilter = new TargetMethodCallbackFilter(); /** * (1)callback1:方法拦截器 (2)NoOp.INSTANCE:这个NoOp表示no operator,即什么操作也不做,代理类直接调用被代理的方法不进行拦截。 (3)FixedValue:表示锁定方法返回值,无论被代理类的方法返回什么值,回调方法都返回固定值。 */ Callback noopCb = NoOp.INSTANCE; Callback callback1 = new TargetInterceptor(); Callback fixedValue = new TargetResultFixed(); Callback[] cbarray = new Callback[]{ callback1, noopCb, fixedValue }; enhancer.setCallbacks(cbarray); enhancer.setCallbackFilter(callbackFilter); TargetObject targetObject2 = (TargetObject)enhancer.create(); System.out.println(targetObject2); System.out.println(targetObject2.method1("mmm1")); System.out.println(targetObject2.method2(100)); System.out.println(targetObject2.method3(100)); System.out.println(targetObject2.method3(200)); } }
- 其中设置了回调过滤器:通过过滤器,决定不同的方法使用不同的回调函数;
- 如上,可以添加更多的 callback2、callback3、callback4 ……;
- 其中设置了多个回调函数:
- “noopCb”:不做操作;
- “callback1”:(见上一节)实现代理逻辑;
- “fixedValue”:返回固定值的回调;
- 如上:method1 将通过代理(“callback1”),method2 并不代理(“noopCb”),method3 方法将返回固定值(“fixedValue”)。
延迟加载对象
CGLib 中,实现延迟加载的方式: 1、“LazyLoader”接口:(继承于“Callback”)只在第一次访问延迟加载属性时触发代理类回调方法; 2、“Dispatcher”接口:(继承于“Callback”)在每次访问延迟加载属性时都会触发代理类回调方法;
示例:
- 实体类 LoaderBean,延迟加载“PropertyBean”和“propertyBeanDispatcher”:
import net.sf.cglib.proxy.Enhancer; public class LazyBean { private String name; private int age; private PropertyBean propertyBean; private PropertyBean propertyBeanDispatcher; public LazyBean(String name, int age) { System.out.println("lazy bean init"); this.name = name; this.age = age; // 延迟加载 propertyBean this.propertyBean = createPropertyBean(); // 延迟加载 propertyBeanDispatcher this.propertyBeanDispatcher = createPropertyBeanDispatcher(); } /** * 只第一次懒加载 * @return */ private PropertyBean createPropertyBean() { /** * 使用cglib进行懒加载 对需要延迟加载的对象添加代理,在获取该对象属性时先通过代理类回调方法进行对象初始化。 * 在不需要加载该对象时,只要不去获取该对象内属性,该对象就不会被初始化了。 * (在CGLib的实现中只要去访问该对象内属性的getter方法,就会自动触发代理类回调)。 */ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(PropertyBean.class); PropertyBean pb = (PropertyBean) enhancer.create(PropertyBean.class, new ConcreteClassLazyLoader()); return pb; } /** * 每次都懒加载 * @return */ private PropertyBean createPropertyBeanDispatcher() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(PropertyBean.class); PropertyBean pb = (PropertyBean) enhancer.create(PropertyBean.class, new ConcreteClassDispatcher()); return pb; } // getter(name、age、propertyBean、propertyBeanDispatcher) ... // setter(name、age、propertyBean、propertyBeanDispatcher) ... @Override public String toString() { return "LazyBean [name=" + name + ", age=" + age + ", propertyBean=" + propertyBean + "]"; } }
- “PropertyBean”类如下:
public class PropertyBean { private String key; private Object value; // getter(key、value) ... // setter(key、value) ... @Override public String toString() { return "PropertyBean [key=" + key + ", value=" + value + "]" + getClass(); } }
- “ConcreteClassLazyLoader”接口(实现了“LazyLoader”):
import net.sf.cglib.proxy.LazyLoader; public class ConcreteClassLazyLoader implements LazyLoader { @Override public Object loadObject() throws Exception { System.out.println("before lazyLoader..."); PropertyBean propertyBean = new PropertyBean(); propertyBean.setKey("xxx"); propertyBean.setValue(new TargetObject()); System.out.println("after lazyLoader..."); return propertyBean; } }
- “ConcreteClassDispatcher”接口(实现了“Dispatcher”):
import net.sf.cglib.proxy.Dispatcher; public class ConcreteClassDispatcher implements Dispatcher{ @Override public Object loadObject() throws Exception { System.out.println("before Dispatcher..."); PropertyBean propertyBean = new PropertyBean(); propertyBean.setKey("xxx"); propertyBean.setValue(new TargetObject()); System.out.println("after Dispatcher..."); return propertyBean; } }
接口生成器(InterfaceMaker)
InterfaceMaker:用于动态生成一个接口,该接口包含指定类定义的所有方法。
示例:
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.InterfaceMaker; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class TestInterfaceMaker { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { InterfaceMaker interfaceMaker = new InterfaceMaker(); //抽取某个类的方法生成接口方法 interfaceMaker.add(TargetObject.class); Class<?> targetInterface = interfaceMaker.create(); for(Method method : targetInterface.getMethods()){ System.out.println(method.getName()); } //接口代理并设置代理接口方法拦截 Object object = Enhancer.create( Object.class, new Class[]{targetInterface}, new MethodInterceptor(){ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { if(method.getName().equals("method1")){ System.out.println("filter method1 "); return "mmmmmmmmm"; } if(method.getName().equals("method2")){ System.out.println("filter method2 "); return 1111111; } if(method.getName().equals("method3")){ System.out.println("filter method3 "); return 3333; } return "default"; }}); Method targetMethod1 = object.getClass().getMethod("method3",new Class[]{int.class}); int i = (int)targetMethod1.invoke(object, new Object[]{33}); Method targetMethod = object.getClass().getMethod("method1",new Class[]{String.class}); System.out.println(targetMethod.invoke(object, new Object[]{"sdfs"})); } }