在java的动态代理中,有两个重要的类或者接口,一个是InvocationHandler(Interface)、另一个是Proxy(Class),这个类和接口是实现动态代理所必须的。
InvocationHandler:每一个动态代理类都必须实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的invoke方法来进行调用。
我们来看看invoke这个方法:
public Object invoke(Object proxy, Method method, Object[] args)
这里面有三个参数分别为proxy,method,args
proxy:指代我们所代理的真实对象
method:指代的是我们所要调用真实对象的某个方法的Method对象
args:指代的是调用真实对象某个方法时接收的参数
Proxy:这个类的作用就是用来动态的创建一个代理对象的类,其接受三个参数
public Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来生成的代理对象进行加载
interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了。
h:一个InvocationHandler对象,表示的是当我这个动态代理在调用方法的时候,会关联到哪一个InvocationHandler对象上
下面我们通过一个例子来理解什么是动态代理
首先创建一个接口
package com.Demo3;
public interface IUserDao {
public void save();
}
然后实现这个接口
package com.Demo3;
public class UserDao implements IUserDao {
@Override
public void save() {
System.out.println("开始数据库的连接.................");
}
}
在写一个代理类
package com.Demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
//目标对象
private Object target;
//构造方法,给我们目标对象赋值
public ProxyFactory(Object target){
this.target = target;
}
//代理对象
public Object getProxyInstance(){
return Proxy.newProxyInstance(target.getClass().getClassLoader()
, target.getClass().getInterfaces()
, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用目标对象方法
System.out.println("开始事务...............");
Object result = method.invoke(target,args);
System.out.println("结束事务................");
return result;
}
});
}
}
最后写一个测试类
package com.Demo3;
public class Test {
public static void main(String []args){
//得到目标对象
UserDao target = new UserDao();
//得到 代理对象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
//执行
proxy.save();
}
}
运行结果
[总结]
看了上面动态代理,接下来我们来看看它有哪些特点
>代理对象不需要实现接口
>代理对象生成,使用到JDK API,动态的在内存中创建代理对象
>动态代理也叫JDK代理,接口代理
>目标对象一定要实现接口,否则不能使用动态代理