通过Java反射机制,可以在程序中访问到已经装载到JVM中的Java对象的描述,实现访问、检测和修改对象本身信息的功能。动态代理技术的意义在于生成一个占位(代理对象),来代理真实对象,从而控制对于真实对象的访问。
代理模式
常用的代理模式有JDK动态代理,CGLIB动态代理等。我们这次主要介绍JDK动态代理。
实现代理主要有两个步骤:
- 真实对象和代理对象建立代理关系。相当于利用原有对象去生成一个新的对象。
- 实现代理对象的代逻辑方法。必须要实现真实对象的逻辑方法,如果不实现,代理也将没有意义。
代码如下:
//JDK代理是基于接口实现的,所以要先建立一个接口
public interface Helloworld {
public void sayHello();
}
//接口的实现类
public class HelloworldImp implements Helloworld {
@Override
public void sayHello() {
System.out.println("hello world");
}
}
/*在Jdk动态代理中,要实现代理逻辑类必要去实现java.lang.reflect.InvocationHandle接口,
它里面定义了一个invoke方法,是代逻辑的实现方法,在这个方法里可以完成对真实逻辑的控制*/
public class JdkProxyExample implements InvocationHandler {
//真实对象
private Object target = null;
/*
* 建立代理对象和真实对象的关系
* @param targer 真实对象
* @return 代理对象
* */
public Object bind(Object target){
this.target=target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
/*
* 代理方法逻辑
* @param proxy 代理对象
* @param method 当前调度方法
* @param args 当前方法参数
* @return 代理结果返回
* throws Throwable 异常
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入代理对象逻辑之前");
Object obj=method.invoke(target,args); //target为之前保存的真实对象,调用此方法相当于调用真实对象的真实逻辑sayHello()方法
System.out.println("进入代理对象逻辑之后");
return null;
}
}
//测试类
public class JdkProxyTest {
public static void main(String[] args) {
JdkProxyExample jdk=new JdkProxyExample();
Helloworld proxy=(Helloworld) jdk.bind(new HelloworldImp());
proxy.sayHello();
}
}
运行结果如下:
进入代理对象逻辑之前
hello world
进入代理对象逻辑之后
可以看出,在逻辑绑定实现类中,首先保存了真实对象,然后代码:Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this); 利用真实对象生成了一个代理对象并将其返回供外界访问。后面调用虚拟方法的代逻辑时,就会执行逻辑绑定实现类中的invoke方法。