java动态代理机制中有两个重要的类和接口InvocationHandler(接口)和Proxy(类),这一个类Proxy和接口InvocationHandler是我们实现动态代理的核心;
1.InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法。
每一个动态代理类的调用处理程序都必须实现InvocationHandler接口,并且每个代理类的实例都关联到了实现该接口的动态代理类调用处理程序中,当我们通过动态代理对象调用一个方法时候,这个方法的调用就会被转发到实现InvocationHandler接口类的invoke方法来调用,看如下invoke方法:
public Object
invoke(Object proxy
, Method method
, Object
[] args
)
throws Throwable
;
2.Proxy类就是用来创建一个代理对象的类,它提供了很多方法,但是我们最常用的是newProxyInstance方法。
public static Object
newProxyInstance(ClassLoader loader
,
Class
<?>[] interfaces
,
InvocationHandler h
)
这个方法的作用就是创建一个代理类对象,它接收三个参数,我们来看下几个参数的含义:
loader:一个classloader对象,定义了由哪个classloader对象对生成的代理类进行加载interfaces:一个interface对象数组,表示我们将要给我们的代理对象提供一组什么样的接口,如果我们提供了这样一个接口对象数组,那么也就是声明了代理类实现了这些接口,代理类就可以调用接口中声明的所有方法。h:一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个InvocationHandler对象上,并最终由其调用。
3、案例
定义一个接口People
public interface IPeople {
public String
work();
}
定义一个Teacher 类实现People接口
public class Teacher implements IPeople {
@Override
public String
work() {
System
.out
.println("老师教书育人...");
return "教书";
}
}
现在我们要定义一个代理类的调用处理程序,每个代理类的调用处理程序都必须实现InvocationHandler接口,代理类如下:
import java
.lang
.reflect
.InvocationHandler
;
import java
.lang
.reflect
.Method
;
public class WorkHandler implements InvocationHandler{
private Object obj
;
IPeople proxy
= null
;
public WorkHandler() {
}
public WorkHandler(Object obj
) {
this.obj
= obj
;
this.proxy
= (IPeople
) Proxy
.newProxyInstance(IPeople
.class.getClassLoader(),
new Class<?>[]{IPeople
.class}, this);
}
public IServiceHandler
getProxy() {
return proxy
;
}
@Override
public Object
invoke(Object proxy
, Method method
, Object
[] args
) throws Throwable
{
System
.out
.println("before invoke。。。");
Object invoke
= method
.invoke(obj
, args
);
System
.out
.println("after invoke。。。");
return invoke
;
}
}
客户端代码
import java
.lang
.reflect
.InvocationHandler
;
import java
.lang
.reflect
.Proxy
;
public class Test {
public static void main(String
[] args
) {
People people
= new Teacher();
IPeople proxy
= new WorkHandler(people
)getProxy();
System
.out
.println(proxy
.work());
}
}