动态代理的作用和实现。

动态代理的原理、作用以及实现

做java学习以及开发的小伙伴们对于动态代理这个词一定不陌生,但是到底什么是动态代理,或许解释起来是有些麻烦。这篇文章的目的也是为了能够让大家更加深刻的理解动态代理。

动态代理,代理顾名思义,像工厂和商家之间的商家一样,商家帮工厂出售产品,工厂则负责制作产品,那么代理类也是一样,你写了一个SayHello类了,然后使用代理类去代替你写的SayHello类,执行类中的方法。

或许经过上面的一番描述,大多数小伙伴们会更加疑惑,哎,我明明已经写了SayHello类了,为啥子不直接用它,而是要去使用一个代理呢?怪麻烦的。

对于SayHello类而言,如果需求不变,那么类可能满足功能,但是如果有一天,对于类SayHello类的需求改变了呢?是不是就需要拓展SayHello类了?这时,代理的作用也就显现出来了。这时候因为SayHello类中的方法,是在代理类中由代理类来调用的,所以在不添加源代码的基础上,也可以实现原方法的拓展。

原理如图:
借用一下某位仁兄的图片该图片作者的博客
在这里插入图片描述

实现代码如下:


//SayHello接口
interface ISayHello{
	void sayHello();
}
//SayHello接口的实现类
class SayHelloImpl implements ISayHello{
	@Override
	public void sayHello(){
		System.out.println("say hello!");
	}
}

//测试类,主要用于测试代理,提供程序入口函数main
public class Main{

	public static void main(String[] args) throws IllegalArgumentException, ClassNotFoundException{
		
		
		 * SayHello接口变量
		 * Proxy是java内置的代理对象
		 * newProxyInstance方法是创建代理对象的方法
		 * newProxyInstance(
		 * 		该参数代表被代理对象的类加载器
		 *  	ClassLoader loader,
		 * 		被代理对象所实现的接口
		 *  	Class<?>[] interfaces,
		 * 		实现代理的接口
		 *  	InvocationHandler h
		 * )
		 * 		通过Proxy的newProxyInstance方法产生的对象,就是一个实现了SayHelloImpl类所实现接口的对象(相当于匿名的SayHelloImpl)
		  
		ISayHello iSayHello = (ISayHello)Proxy.newProxyInstance(
				//被代理类为SayHelloImpl,获取它的类加载器
				Class.forName("cn.zzcfirst.SayHelloImpl").getClassLoader(),
				//获取被代理类SayHelloImpl所实现的接口 
				Class.forName("cn.zzcfirst.SayHelloImpl").getInterfaces(), 
				//创建匿名InvocationHandler对象,重写invoke方法,在代理类调用被代理类的方法时,进入InvocationHandler的invoke方法
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println("添加拓展功能");
						//利用反射执行SayHelloImpl对象的方法,改invoke与上面的invoke不同
						method.invoke(
								Class.forName("cn.zzcfirst.SayHelloImpl").newInstance(),args);
						System.out.println("添加拓展功能");
						//此处返回null是因为我所调用的方法没有返回值
						//此处的返回值可以写为(对于方法有返回值)
						//return method.invoke(被代理类对象,方法所需参数);
						return null;
					}
		});
		//使用代理对象,调用SayHelloImpl类中的方法。
		iSayHello.sayHello();
	}
}

在上面的例子中,我开始创建了SayHelloImpl类,但是我想为它的sayHello方法添加其他功能,但是又不想改动原有方法,就可以利用动态代理去为其增加新的功能,而且使用动态代理还可以隐藏原有SayHelloImpl类的实现,例如使用上述代理对象,可能功能与原有类相同,但是调用者却不知道原有sayHello。

发布了6 篇原创文章 · 获赞 0 · 访问量 121

猜你喜欢

转载自blog.csdn.net/AC_sunK/article/details/103568888
今日推荐