代理模式
来源:互联网 发布:12c5a60怎么使用p4端口 编辑:程序博客网 时间:2024/05/29 16:23
图1:Proxy模式
按照代理类的创建时期,代理类可分为两种。
- 静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
- 动态代理类:在程序运行时,运用反射机制动态创建而成。
静态代理类的实现:
1. 定义一个IService接口
- package cn.lettoo.proxy;
- public interface IService {
- void execute();
- }
package cn.lettoo.proxy;public interface IService { void execute();}
2. 具体的实现类:
- package cn.lettoo.proxy;
- public class PrintService implements IService {
- public void execute() {
- System.out.println("The Print Service works.");
- }
- }
package cn.lettoo.proxy;public class PrintService implements IService { public void execute() { System.out.println("The Print Service works."); }}
3. 代理类:
- package cn.lettoo.proxy;
- public class PrintServiceProxy implements IService {
- IService printSerivce;
- public PrintServiceProxy(IService service) {
- this.printSerivce = service;
- }
- public void setPrintSerivce(IService printSerivce) {
- this.printSerivce = printSerivce;
- }
- public void execute() {
- this.beforePrint();
- this.printSerivce.execute();
- this.afterPrint();
- }
- private void beforePrint() {
- System.out.println("Before print.");
- }
- private void afterPrint() {
- System.out.println("Before print.");
- }
- }
package cn.lettoo.proxy;public class PrintServiceProxy implements IService { IService printSerivce; public PrintServiceProxy(IService service) { this.printSerivce = service; } public void setPrintSerivce(IService printSerivce) { this.printSerivce = printSerivce; } public void execute() { this.beforePrint(); this.printSerivce.execute(); this.afterPrint(); } private void beforePrint() { System.out.println("Before print."); } private void afterPrint() { System.out.println("Before print."); }}
代理类的execute()方法只是调用了被代理的Service的execute方法,被代理的Service通过构造函数或者set的方式被注入到代理对象中。同时,代理对象也有一些自己的代理方法,如本例中在被代理类的execute()方法调用前后加上自己的方法。
4. 客户调用代码:
- package cn.lettoo.proxy;
- public class Client {
- public static void main(String[] args) {
- IService service = new PrintService();
- IService proxy = new PrintServiceProxy(service);
- proxy.execute();
- }
- }
package cn.lettoo.proxy;public class Client { public static void main(String[] args) { IService service = new PrintService(); IService proxy = new PrintServiceProxy(service); proxy.execute(); }}
The Print Service works.
Before print.
动态代理的实现:
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
Proxy类提供了创建动态代理类及其实例的静态方法。
Porxy有两种方式来生成代理对象:
方法1:
- //创建InvocationHandler对象
- InvocationHandler handler = newMyInvocationHandler(...);
- //创建动态代理类,IService是被代理的接口
- Class proxyClass = Proxy.getProxyClass(IService.class.getClassLoader(), new Class[] { IService.class });
- //创建动态代理类的实例
- IService proxyService = (IService) proxyClass.getConstructor(new Class[] { invocationHandler.class }).newInstance(new Object[] { handler });
//创建InvocationHandler对象InvocationHandler handler = newMyInvocationHandler(...);//创建动态代理类,IService是被代理的接口Class proxyClass = Proxy.getProxyClass(IService.class.getClassLoader(), new Class[] { IService.class });//创建动态代理类的实例IService proxyService = (IService) proxyClass.getConstructor(new Class[] { invocationHandler.class }).newInstance(new Object[] { handler });
方法2:
- //创建InvocationHandler对象
- InvocationHandler handler = newMyInvocationHandler(...);
- //直接创建动态代理类的实例
- IService serviceProxy = (IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class[] { IService.class },
- handler);
//创建InvocationHandler对象InvocationHandler handler = newMyInvocationHandler(...);//直接创建动态代理类的实例IService serviceProxy = (IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class[] { IService.class },handler);
InvocationHandler 接口为方法调用接口,它声明了负责调用任意一个方法的invoke()方法:
- Object invoke(Object proxy,Method method,Object[] args) throws Throwable
Object invoke(Object proxy,Method method,Object[] args) throws Throwable
代码实现:
1. 写一个ServiceFactory,用于生成代理对象
- package cn.lettoo.proxy;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- public class ServiceFactory {
- public static IService getServiceProxy(final IService service) {
- InvocationHandler handler = new InvocationHandler() {
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- beforePrint();
- Object result = method.invoke(service, args);
- afterPrint();
- return result;
- }
- };
- return (IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class[] { IService.class },
- handler);
- }
- private static void beforePrint() {
- System.out.println("Before print.");
- }
- private static void afterPrint() {
- System.out.println("Before print.");
- }
- }
package cn.lettoo.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ServiceFactory { public static IService getServiceProxy(final IService service) { InvocationHandler handler = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { beforePrint(); Object result = method.invoke(service, args); afterPrint(); return result; } }; return (IService) Proxy.newProxyInstance(IService.class.getClassLoader(), new Class[] { IService.class }, handler); } private static void beforePrint() { System.out.println("Before print."); } private static void afterPrint() { System.out.println("Before print."); } }
2. 客户端代码:
- package cn.lettoo.proxy;
- public class Client {
- public static void main(String[] args) {
- IService service = new PrintService();
- IService proxy = ServiceFactory.getServiceProxy(service);
- proxy.execute();
- }
- }
package cn.lettoo.proxy;public class Client { public static void main(String[] args) { IService service = new PrintService(); IService proxy = ServiceFactory.getServiceProxy(service); proxy.execute(); }}
The Print Service works.
Before print.
也许有人要问,采用动态代理有什么好处?那么我告诉你,你不需要为每个IService的实现类都去写一个Proxy类了(前提是代理方法是一样的),假如,我现在有另外一个IService的实现类如下:
- package cn.lettoo.proxy;
- public class AnotherService implements IService {
- public void execute() {
- System.out.println("I am another service.");
- }
- }
package cn.lettoo.proxy;public class AnotherService implements IService { public void execute() { System.out.println("I am another service."); }}
现在客户端只要这样写:
- public static void main(String[] args) {
- IService service = new AnotherService();
- IService proxy = ServiceFactory.getServiceProxy(service);
- proxy.execute();
- }
public static void main(String[] args) { IService service = new AnotherService(); IService proxy = ServiceFactory.getServiceProxy(service); proxy.execute(); }
I am another service.
Before print.
可以看到,不需要单独再为AnotherService写一个代理类了,动态代理类会帮助我们去实现的。
- 代理模式--动态代理
- 代理模式-静态代理
- 代理模式-静态代理
- 代理模式 & 动态代理
- 代理模式--静态代理
- 代理模式--动态代理
- 代理模式(动态代理)
- 代理模式-动态代理
- 代理模式-动态代理
- 代理模式动态代理
- 代理模式-静态代理
- 代理模式-动态代理
- 代理模式 -动态代理
- 代理模式---动态代理
- 代理模式-动态代理
- 代理模式--静态代理
- 代理模式!
- 代理模式
- 评审
- iup ftp 上传配置。
- 设计模式与泡MM的关系
- 关于directfb下的inputdriver里的键盘设备
- JS中window.setInterval和window.setTimeout的区别
- 代理模式
- Objective-C最基础语法之基础类型
- tomcat容器的编码设置
- 关于tomcat
- PreparedStatement设值where in语句
- 原来IIS服务器是可以架设JSP服务器的
- 感触
- getSystemService 笔记
- windows 自动登录