java动态代理学习

先理解代理目标的概念:
举例来说:
金士顿厂家生产U盘但是不直接卖给用户,是经过代理商来卖的
代理商可以是淘宝,可以是京东,可以是拼多多
那么此时,淘宝,京东,拼多多就是代理,
金士顿厂商就是目标,
先看静态代理:
静态代理的3个步骤:
1)定义一个接口,接口中包含目标和代理都要实现的方法
2)目标类实现接口
3)代理类包含目标对象,调用目标对象的方法,并增强实现

具体操作如下:
1,定义一个接口,接口里面定义了目标厂家和代理商要实现的功能
比如这里的目标厂商金士顿和代理商淘宝都要实现卖U盘的功能

public interface usbsell {
void sell();
}

2,目标类实现接口

public class kingstonFactory implements usbsell {

	@Override
	public void sell() {
		System.out.println("目标类:工厂卖U盘 85元一个");
		
	}

} 

3.代理类包含目标对象,并利用目标对象 调用目标对象的方法,并且可增强功能

public class taobao implements usbsell{

	//代理类要想调用目标类的方法 就要包含目标对象
	kingstonFactory kf=new kingstonFactory();
	public void sell() {
		//利用目标对象 调用目标对象里面的方法
		kf.sell();
		//增强实现
		System.out.println("增强实现,淘宝给买U盘的用户送一个小礼品");
		
	}

}

4测试

public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		taobao tb=new taobao();
		tb.sell();

	}

}

输出结果:
在这里插入图片描述
静态代理的优缺点:
优点:简单
缺点:
静态代理的3个步骤:
1)定义一个接口,接口中包含目标和代理都要实现的方法
2)目标类实现接口
3)代理类包含目标对象,调用目标对象的方法,并增强实现

由静态代理的3个步骤可知:
如果目标工厂有多个,那么就要创建多个代理类
比如除了金士顿,还有三星,闪迪卖U盘,这些厂家都是目标,那么不仅要创建这三个目标类,还要创建三个代理类
代码的重用性不强

动态代理
动态代理的步骤:

1定义一个公共接口,接口中定义了目标类和代理类都要实现的方法;比如代理商和工厂都要实现卖U盘接口

public interface factorySell {
	void sell();

}

2 目标类实现这个接口,

public class kingstonFactory implements factorySell{

	@Override
	public void sell() {
		System.out.println("目标方法:金士顿原厂卖U盘85元一个");
		
	}
	
}

3 定义一个 myhandler 实现 InvocationHandler接口,
接口里面有一个invoke方法,在这个方法里面通过反射调用目标类中的方法,并且可以增强实现。

值得注意的是,这个handler接口的实现类,要通过构造方法来从外界获取目标对象target,这为下面invoke 方法中 method.invoke(target, args);打下了基础
,这样,你想要执行哪个代理类的sell方法,就传那个代理类的对象。

public class myhandler implements InvocationHandler{
	//用构造方法接收传入的目标对象
	Object target=null;
	myhandler(Object target){
		this.target=target;
	}
	

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//通过反射调用目标对象的方法
	     method.invoke(target, args);
	     //增强实现
		System.out.println("代理类对原厂方法进行了增强,一个U盘100元");
		return null;
	}

}

这个method.invoke(target, args);要搞清楚,
method指的是公共接口中定义的方法,本例中是usbsell接口中定义的方法
target指的是由程序员指定的,本例中是通过myhandler类的构造函数,接收到的目标对象,也就是金士顿工厂对象
搞清楚这一点,才能搞清楚当invoke执行时,到底是哪个类的哪个方法被调用了,很明显是目标类中实现了的公共接口中的方法被调用了,比如目标类(金士顿工厂类)实现了usbsell接口中的sell方法,

4调用Proxy中的静态方法 newProxyInstance来实现动态代理

Proxy.newProxyInstance(ClassLoader loader, //目标类对应的类加载器
Class<?>[] interfaces, //目标类对应的接口,这里指的就是卖U盘的接口
InvocationHandler h // 实现了InvocationHandler接口的那个类的对象
)

在这里插入图片描述
图1:

Proxy中的静态方法 newProxyInstance返回一个代理对象,这个代理对象中包含上图中, newProxyInstance函数的第二个参数 接口中定义的方法,例如本例中的接口usbsell中就定义了一个方法sell(),
那么调用newProxyInstance返回一个代理对象proxy,这个代理对象就可以直接调用sell方法,proxy.sell();
但是值得注意的是,调用这个sell方法就像启动了InvocationHandler接口中的invoke方法一样,不仅会调用目标对象的sell 方法,还会调用增强方法,也就是把invoke中的方法都执行一遍,这是很奇怪的,明明只调用了sell方法,却把invoke方法执行了一遍
测试类:
**public class test {

public static void main(String[] args) {
	kingstonFactory mubiaoleiDuixiang=new kingstonFactory();
	
	factorySell dailileiDX=(factorySell) Proxy.newProxyInstance(mubiaoleiDuixiang.getClass().getClassLoader(),
			               										mubiaoleiDuixiang.getClass().getInterfaces(), 
			               										new myhandler(mubiaoleiDuixiang));
	
	dailileiDX.sell();
}

}**
在这里插入图片描述
动态代理的优点:
1.相比于静态代理,静态代理创建一个目标类之后,还需要创建一个代理类,
而动态代理只需要创建目标类,而不需要创建代理类了,这样一来,如果你在接口里面添加一个方法,那么只需要改动一下目标类即可,不需要像静态代理那样,目标类和代理类都要改。
2,如果有多个代理对象,每个代理对象增强实现的方法不一样,比如代理类不仅有淘宝,还有京东,微商,拼多多,每个代理要实现的增强不一样,那么
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值