代理模式,和动态代理

代理模式和动态代理,都是来解决增强的

代理模式

	1.4个元素,被代理的接口,被代理的实现类,被代理的实现类的对象,代理类
	2.代理类 实现了 被代理的 接口
	3.向代理类中,传被代理的实现类
	4.代理类 重写 接口的所有方法,在这些方法中,调用实现的方法,然后可以在这个
	  方法前后做增强
	5.例子:
		interface IHello{
			void sayHello();
			void sayGoodBye()
		}
		class IHelloImplement implements IHello{
			void sayHello(){
				sout("say hello!!!");
			}
			void sayGoodBye(){
				sout("say goodBye!!!");
			}
		}
		这时如果要做增强,但是不能改源代码,那么我想只能重新写一个类去实现接口
		然后,将之前的实现类传过来,这样在保持之前实现类不变的情况下,可以做增强
		class Proxy implements IHello{
			private IHello iHello;
			public void setIHello(IHello iHello){
				this.iHello = iHello;
			}
			void sayHello(){
				sout("增强");
				iHello.sayHello();
			}
			void sayGoodBye(){
				sout("增强");
				iHello.sayGoodBye();
			}
		}
		这样,我们有了这个代理类,就可以做到增强

动态代理

	1.五个元素,被代理接口,被代理接口实现类,InvocationHandler实现类,Proxy类(动态创建,代理对象的)
		被代理实现类的对象(传给InvocationHandler)
	2.Proxy和InvocationHandler的区别
		1.Proxy可以动态创建 需要被代理的实现类的对象
	     这个需要被代理的实现类的对象执行方法时,会调用 InvocationHandler实现类的 invoke()方法
		 执行的不是被代理接口实现类的方法,执行的是invoke增强的方法
	3.代理模式的代理对象,就是自己创建的代理类的对象
	  而动态代理的代理对象,仅是,之前未被增强的 实现类的 对象
	  只是,这个对象在执行方法的时候,会调用Invocationhandler的invoke方法
	  在invoke的方法里面,我们做了增强
	4.代理模式和动态代理增强的位置不同
		1.代理模式:自己写的代理类,实现接口的方法的时候,做了增强
		2.动态代理:InvocationHanler
		接口实现类的 invoke方法做了增强
	5.Invocation的实现类,可以看做代理对象,Proxy创建出来的可以看做需要被代理的实现类对象

	5.动态代理的具体步骤:
		1.创建InvocationHandler实例
			1.创建一个需要被代理的实现类对象,传给InvocationHandler
			2.这样InvocationHander属性中就有了,一个实现类对象
			3.必须传,因为最后 invoke(Object object, Method method, Object[] args)
			  中的, method.invoke(subject, args);,subject就是来自这个对象的
			
		2.Proxy创建 具体的动态代理对象
			newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
				loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
					    一般是,传被代理实现类的 classLoader
					    作用:生成代理对象
				interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,
							如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),
							这样我就能调用这组接口中的方法了
							传之前与InvocayionHandler绑定的需要被代理的实现类对象的interfaces
							作用:生成代理对象可以执行哪些方法
				
				h: 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
							传之前创建的handler
							作用:当代理对象执行方法后,会关联InvocationHandler对象,去执行真正的invoke方法
		
		3.可以理解需要将 handler和需要被代理的实现类对象要做一次绑定
		
		  	1.而Proxy做绑定的时候,重点就是Class<?>[] interfaces, InvocationHandler h,这两个参数
		  	interface必须传,需要被代理的实现类对象的interface
		  	h必须传 有这个实现类对象作为属性的 invocationhandler实例
		  	这样 Proxy返回的 才是 之前那个创建好的,需要被代理的实现类对象
		  	执行的时候,因为绑定了,也能找到具体的 invocationHandler,执行invoke
		  	invoke也能执行,这个需要被代理的实现类对象的方法,因为之前我的InvocationHandler里面传了它
		  	
		  	2.这样就能理解,为什么InvocationHandler里面要有一个 需要被代理的实现类对象属性

一个InvocationHandler的 invoke方法如何增强 一个 proxy的 多个 method?

	在 invoke方法里面做一个判断即可,判断method类型,多个if就可以解决

容易被忽视的,就是Proxy中的 接口方法,生成的proxy代理对象,只有在调用被代理的 接口方法的时候,才会调用invocationHandler的 invoke方法,例如拦截器的拦截规定(signature修饰的 那个对象的那个方法),生成代理对象后,只有在执行这个方法的时候,才会调用invocationHandler的 invoke方法

invocationHandler和invocation的区别

	1.invocationhandler是执行具体invoke的地方
	2.invocation可以保存 代理对象和方法和args,这样在invoke方法如果不在此处执行
	例如interceptor中是最后传这个invocation给interceptor的intercept方法去执行
	3.invocation可以保存proxy中的需要被代理的对象,以及他的 method,agrs,invoke调用其他方法后
	还是可以通过invocation获得代理对象的信息,对象,方法,参数,继续执行代理对象的方法
静态代理模式动态代理模式都是常用的软件设计模式,它们主要用于创建对象的实例并控制其行为。在这两个例子中,我们将设计一个基础的简单计算器,分别通过静态代理动态代理的方式实现。 **1. 静态代理模式** 在这个模式下,我们首先创建一个`Calculator`接口,然后定义一个具体的`AddCalculator`作为静态代理类: ```java // Calculator 接口 public interface Calculator { int add(int a, int b); } // 具体实现 - AddCalculator (静态代理) public class AddCalculator implements Calculator { private final Calculator delegate; public AddCalculator() { delegate = new BasicCalculator(); // 实现基础加法计算 } @Override public int add(int a, int b) { return delegate.add(a, b); // 调用实际的加法操作 } } ``` `BasicCalculator`是一个基础的计算器实现,负责做加法运算。 **2. 动态代理模式(Java语言通常使用CGLIB或JDK动态代理)** 首先创建接口 `Calculator` 基本实现 `BasicCalculator`,然后利用动态代理创建 `ProxyCalculator` 类: ```java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 动态代理的InvocationHandler实现 public class CalculatorProxyHandler implements InvocationHandler { private final Calculator target; public CalculatorProxyCalculator(Calculator target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before method call"); Object result = method.invoke(target, args); System.out.println("After method call"); return result; } } // 使用动态代理创建 public static Calculator createDynamicCalculator(Calculator target) { return (Calculator) Proxy.newProxyInstance( Calculator.class.getClassLoader(), new Class<?>[]{Calculator.class}, new CalculatorProxyHandler(target)); } ``` 现在你可以用这两种方式创建计算器,例如: ```java Calculator staticProxy = new AddCalculator(); Calculator dynamicProxy = createDynamicCalculator(new BasicCalculator()); int result1 = staticProxy.add(1, 2); int result2 = ((Calculator) dynamicProxy).add(3, 4); System.out.println("Result1: " + result1); System.out.println("Result2: "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值