用易语言做网站,沧州手机网站建设,网站设计建,做很多网站文章目录 概念结构实例静态代理动态代理 总结 概念
代理模式#xff1a;给某一个对象提供一个代理或占位符#xff0c;并由代理对象来控制对原对象的访问。 比如我们想从其他国家买东西#xff0c;但我们无法直接联系外国的商家#xff0c;可以找代理商#xff0c;让他们… 文章目录 概念结构实例静态代理动态代理 总结 概念
代理模式给某一个对象提供一个代理或占位符并由代理对象来控制对原对象的访问。 比如我们想从其他国家买东西但我们无法直接联系外国的商家可以找代理商让他们帮我们处理我们是客户端只需要面向代理商即可只需要把钱交给代理商剩下的那些操作比如联系商家、和商家签订协议等我们都不需要关心。
结构 Subject(抽象主题)它是代理类和真实类的共同接口这样一来在任何使用真实对象的地方都可以使用代理对象客户端通常需要针对抽象主题角色进行编程。 Proxy(代理类) 它包含了真实对象的引用所以可以在任何时候操作真实对象。一般在调用真实对象前后还需要执行其他操作。 RealSubject(真实类–被代理类)真实类中实现了主要的业务操作。客户端可以调用代理类来间接的调用真实类。
实例
静态代理
我们想从海外买台电脑用代理模式实现这个流程。
购买东西的接口
public interface IBuySomething {void pay();
}
真实类也就是被代理类
public class Person implements IBuySomething{Overridepublic void pay() {System.out.println(付款);}
}代理商也就是代理类他来帮我们联系商家
public class Agent implements IBuySomething {private IBuySomething person;public Agent(IBuySomething person) {this.person person;}Overridepublic void pay() {findBusiness();person.pay();}private void findBusiness() {System.out.println(我是代理商付款之前先找到商家);}
}客户端
public class Client {public static void main(String[] args) {IBuySomething person;person new Agent(new Person());person.pay();}
}打印结果 也可以让代理商来替我们的朋友来买东西只需要再声明一个朋友类让代理商来代理即可。
朋友类
public class Friend implements IBuySomething{Overridepublic void pay() {System.out.println(我是朋友我付款);}
}客户端
public class Client {public static void main(String[] args) {IBuySomething person;person new Agent(new Friend());person.pay();}
}打印结果 反过来如果想换一家代理商那就再创建一个新的代理商类即可。
public class Agent2 implements IBuySomething{private IBuySomething person;public Agent2(IBuySomething person) {this.person person;}Overridepublic void pay() {findBusiness();person.pay();}private void findBusiness() {System.out.println(我是另外一个代理商付款之前先找到商家);}
}动态代理
以上的这种代理方式叫做静态代理。 静态代理的特点是一个代理类只能代理一个真实类或者只能代理一个方法。因为它在执行前就编译成了class文件不会进行改变了所以被称为静态代理。 但如果我们想动态的代理不同的真实类或者代理不同的方法可以使用动态代理来实现。动态代理可以让系统在运行时根据实际需求来动态的创建代理类。 有关动态代理有两个重要的类。 Proxy类 Proxy类提供了用于创建动态代理对象的方法。它的主要方法newProxyInstance public static Object newProxyInstance(ClassLoader loader,Class?[] interfaces,InvocationHandler h)该方法即用来创建一个动态代理对象第一个参数是代理类的类加载器作用是将.class文件加载到jvm中进而生成一个对象实例第二个参数是真实类实现的接口列表第三个是执行代理方法的具体程序—InvocationHandler。 简单总结下要想生成一个代理对象首先得创建class对象第一个参数的作用其次得知道代理谁第二个参数的作用最后代理的方法是什么第三个参数。这样看来第二个和第三个参数都是动态的可变的这也就是代理模式的灵活性。
InvocationHandler 上面的第三个参数InvocationHandler 是一个接口它只有一个invoke方法
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;该方法用来处理代理类实例的代理方法并返回相应的结果。即我们代理的方法写在这个方法里。 第一个参数是代理对象第二个参数是需要代理的方法第三个参数是需要执行代理方法的参数。
还是拿买东西的例子来说我们如果买完东西后发现不合适需要退款这时候我们面向的还是代理商但如果用静态代理的话那还是需要再写一个代理退款的类如果业务方法更多的话那我们需要创建更多的静态代理类这样处理起来很麻烦。如果用动态代理的话就没有这么冗余。我们首先实现一个InvocationHandler它的invoke方法是用来实现代理对象的方法。
public class AgentHandler implements java.lang.reflect.InvocationHandler {private Object object;public AgentHandler(Object object) {this.object object;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {findBusiness();Object result method.invoke(object, args);return result;}private void findBusiness() {System.out.println(我是代理商我要先找到商家);}
}我们也增加一个退款的方法
public interface IBuySomething {void pay();void refund();
}客户端调用
public class Client {public static void main(String[] args) {IBuySomething person new Person();InvocationHandler handler new AgentHandler(person);Object o Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), handler);IBuySomething proxy (IBuySomething) o;proxy.refund();}
}打印结果
总结
静态代理比较好理解代理类里面实现了代理的方法。 而动态代理的代理对象是通过Proxy创建的代理的方法是在InvocationHandler里的invoke方法里和静态代理对比的话代理类和代理方法是分离开的。