JDK动态代理技术

一.什么是动态代理

动态代理就是为了生成一个代理对象,来代理真实对象,从而来控制真实对象的访问。比如,一家软件公司,有商务负责接待客户,软件工程师负责制作软件。当客户来谈业务时,找的是商务,客户就认为商务代表公司,但是真正完成客户需求的是工程师。这时可以认为商务就是代理对象,来代理工程师,起的是客户与工程师之间的中介作用。
当一个代理对象想代理真实对象时,需要两步,一是要和真实对象建立代理关系,二是要实现代理对象的代理逻辑方法。二者缺一不可。
Java中有很多动态代理技术,但常用的只有JDK,CGLIB。

二.JDK动态代理

JDK动态代理是java.lang.reflect.*包提供,它有一个大前提,必须借助一个接口才能实现代理对象。所以先定义接口。

package 动态代理;
public interface Hello {
	public void sayHello();
}

然后有实现类来实现接口

package 动态代理;
public class HelloImpl implements Hello {
	@Override
	public void sayHello() {
		// TODO Auto-generated method stub
		System.out.println("Hello World!");
	}
}

有了接口和实现类,满足了JDK动态代理的大前提,现在可以开始动态代理了。我们之前说了,要有两步,一建立代理对象与真实对象的关系,二实现代理逻辑
在JDK动态代理中,实现代理逻辑类必须实现java.lang.reflect.InvocationHandler接口,它有一个Invoke方法需要实现。

package 动态代理;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxyExample implements InvocationHandler {
	//真是对象
	private Object target=null;
	public Object bind(Object target){
		this.target=target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("进入代理逻辑方法");
		System.out.println("在调用真实对象前的服务");
		Object obj = method.invoke(target, args);
		System.out.println("在调用真实对象后的服务");
		return obj;
	}
}

首先建立代理对象与真实对象的关系。代码中通过bind方法完成,首先用类的属性target来保存了真实的需要代理的对象,然后通过下列代码建立并生成代理对象。

Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);

Proxy.newProxyInstance()方法来生成代理对象,需要传递三个参数
第一个:类加载器
第二个:把生成对象挂在了哪些接口下,写目标类(被代理类)实现的接口即可
第三个:定义实现代理逻辑的代理类,该类需要实现InvocationHandler接口的Invoke方法,所以我们传入当前对象this。
完成了代理对象与真实对象关系的建立,下一步需要实现代理的逻辑方法,代理的逻辑方法在invoke方法中完成。有代码所示,invoke方法自动传入三个参数
第一个:proxy代理对象,就是上面bind方法生成的代理对象。
第二个:当前调度的方法
第三个:调度的方法的参数
当进入方法中后,它会进入invoke方法里调用真实对象(被代理对象)的方法,只是是通过反射实现。
测试类:

package 动态代理;
public class Test {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JDKProxyExample jdk =new JDKProxyExample();
		Hello proxy = (Hello) jdk.bind(new HelloImpl());
		proxy.sayHello();
	}
}

可以通过打断点调试的方式,更好的理解整个流程,一定要掌握好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值