直接上代码
前提
这里需要结合另一篇博文来理解:
代码
接口:
package com.xmonster.demo2;
public interface IService {
public void sayHello();
}
真实实现类:
package com.xmonster.demo2;
public class RealService implements IService{
@Override
public void sayHello() {
System.out.println("hello i am xmonster!");
}
}
工具+测试:
package com.xmonster.demo2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class SimpleInvocationHandler implements InvocationHandler {
private Object realObj;
public SimpleInvocationHandler(Object realObj) {
this.realObj = realObj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("entering"+method.getName());
Object invokeResult = method.invoke(realObj, args);
System.out.println("leaving"+method.getName());
return invokeResult;
}
public static void main(String[] args) {
IService realService = new RealService();
IService proxy =(IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class<?>[]{IService.class},
new SimpleInvocationHandler(realService));
proxy.sayHello();
}
}
测试结果:
newProxyInstance
来看看newProxyInstance的三个参数
private static Object newProxyInstance(ClassLoader loader, // null if no SecurityManager
Constructor<?>[] interfaces,
InvocationHandler h)
参数:
- ClassLoader loader表示类加载器,在这里使用和接口一样的类加载器
- interfaces表示代理类要实现的接口列表,是一个数组,
元素的类型只能是接口,不能是普通类
- InvocationHandler 它是一个接口,只定义了一个invoke方法,对代理接口所有方法的调用都会转给这个方法来处理
newProxyInstance的返回值是Object,可以被强转为interfaces数组当中的某个接口类型
,在这里直接强转为了IService类型,注意:它不能够被强转为某个类,比如RealService !
InvocationHandler
package java.lang.reflect;
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
参数:
- proxy表示代理本身,注意,他不是被代理的对象
- method表示正在被调用的方法
- args表示方法的参数
Object invokeResult = method.invoke(realObj, args);
这里调用的是method的invoke方法,传递的是实际的对象realObj
,不能将proxy作为参数传递给method.invoke,会出现死循环,因为它本身就有这个方法
以下是method的invoke方法源码
@HotSpotIntrinsicCandidate
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz,
Modifier.isStatic(modifiers) ? null : obj.getClass(),
modifiers);
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}