代理模式,个人认为就是把你要使用的一个对象尽享封装,包装。编程原对象的一个副本,在使用的时候直接使用他这个副本就可以了!他的作用用专业点的语言描
述就是为其他的对象提供一个代理方便控制这个对象。当我们不能直接调用另外一个对象,但是又不得不用这个对象的某些功能,此时代理对象就能起到链接客户和
目标对象的一个代理.
代理模式一般涉及到三个角色,分别为:
1. 抽象角色:他提供真实对象和代理对象的共同接口。
2. 代理角色:通俗地说,代理角色是对原对象(目标对象)进行包装,他有着和原对象相同的接口,并且可以执行真实对象的操作。
3. 真实角色:即目标对象,最终我们需要对他的操作。
代理模式分为两种,一 静态代理,二 动态代理。
接下来我们介绍一下两种代理模式:
一 静态代理
静态代理即 代理对象和被代理对象在代理之前已经确定好了。他们一起实现相同的接口或者是继承相同的抽象类。例如:
-
- public abstract class AbsRole{
- abstract public void work();
- }
//定义抽象角色
public abstract class AbsRole{
abstract public void work();
}
-
- public class RealRole extends AbsRole{
- public RealRole(){ }
-
- public void work(){
- System.out.println("调用真实角色中函数!");
- }
- }
//定义真实角色
public class RealRole extends AbsRole{
public RealRole(){ }
public void work(){
System.out.println("调用真实角色中函数!");
}
}
-
- public class ProxyRole extends AbsRole{
- public RealRole real ;
-
- public ProxyRole(){
- }
-
- public void work(){
- this.beforeMethod();
- if(real == null){
- real = new RealRole();
- }
- real.work();
- this.endMethod();
- }
-
- public void beforeMethod(){
- System.out.println("代理前执行函数->beforeMethod()");
- }
-
- public void endMethod(){
- System.out.println("代理时候后执行函数->endMethod()");
- }
- }
//代理角色
public class ProxyRole extends AbsRole{
public RealRole real ;
public ProxyRole(){
}
public void work(){
this.beforeMethod();
if(real == null){
real = new RealRole();
}
real.work();
this.endMethod();
}
public void beforeMethod(){
System.out.println("代理前执行函数->beforeMethod()");
}
public void endMethod(){
System.out.println("代理时候后执行函数->endMethod()");
}
}
各种角色我们都已经定义好了,我们开始测试一下。
- public class Main(){
- public static void main(String[] args){
- AbsRole ar = new ProxyRole();
- ar.work();
- }
- }
public class Main(){
public static void main(String[] args){
AbsRole ar = new ProxyRole();
ar.work();
}
}
二 动态代理
顾名思义,就是不知道到底那个类需要做代理,在使用的时候,更具情况临时决定。
java动态代理主要是使用java.lang.reflect包中的两个类。
1. interface InvocationHandler: 他中定义了一个方法
- public Object invoke(Object obj,Method method,Object[] obs)
public Object invoke(Object obj,Method method,Object[] obs)
其中第一个参数 obj 指的是代理类,method是被代理的方法,obs是指被代理的方法的参数组。此方法由代理类来实现。
2. Proxy:该类为动态代理类,主要包括以下内容:
- protected Proxy(InvocationHandler h);
-
- static Class getProxyClass(ClassLoader loader,Class[] interfaces);
-
- static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler h);
protected Proxy(InvocationHandler h);
static Class getProxyClass(ClassLoader loader,Class[] interfaces);
static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler h);
动态代理其实是在运行时生成class,所以,我们必须提供一组interface,然后告诉他class已经实现了这些interface,而且在生成Proxy的时候,必须给他提供一个handler,让他来接管实际的工作。
现在我们把静态代理的例子修改一下:
-
- public interface AbsRole{
- public void work();
- }
//定义抽象角色;
public interface AbsRole{
public void work();
}
接下来定义真实角色;
- public class RealRole implements AbsRole{
- public RealRole(){};
-
- public void work(){
- System.out.println("调用真实角色方法:RealRole.work()");
- }
- }
public class RealRole implements AbsRole{
public RealRole(){};
public void work(){
System.out.println("调用真实角色方法:RealRole.work()");
}
}
然后书写动态代理编码
- public class DynamicProxyRole implements InvocationHandler{
- private Object sub;
-
- public DynamicProxyRole(){}
-
- public DynamicProxyRole(Object ob){
- this.sub = ob;
- }
-
- public Object invoke(Object proxy, Method method, Object[] obs) throws Throwable{
- method.invke(sub,obs);
- return null;
- }
- }
public class DynamicProxyRole implements InvocationHandler{
private Object sub;
public DynamicProxyRole(){}
public DynamicProxyRole(Object ob){
this.sub = ob;
}
public Object invoke(Object proxy, Method method, Object[] obs) throws Throwable{
method.invke(sub,obs);
return null;
}
}
代理类已经书写完毕,看看是否能正常运行。
- public class Main{
- public static void main(String[] args){
- RealRole rr = new RealRole();
- InvocationHandler dynamicProxy = new DynamicProxyRole(rr);
- Class<?> cls = rr.getClass();
-
- AbsRole r = (AbsRole)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),DynamicProxyRole);
- r.work();
- }
- }
public class Main{
public static void main(String[] args){
RealRole rr = new RealRole();
InvocationHandler dynamicProxy = new DynamicProxyRole(rr);
Class<?> cls = rr.getClass();
AbsRole r = (AbsRole)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),DynamicProxyRole);
r.work();
}
}
调试成功,动态代理功能完成。
通过静态代理和动态代理学习,我们小结一下:
静态代理需要事先确定代理对象和被代理对象,他们要一起继承或者是实现相同的抽象类。动态代理可以在使用的时候传入真实对象,得到代理。动态代理还是主要依靠java本身的语言特性,实现代理,更加方便