java设计模式---代理模式
来源:互联网 发布:戴尔服务器数据恢复 编辑:程序博客网 时间:2024/05/12 15:15
1.代理模式的整体构架
(1)代理与被代理共同的接口
(2)代理
(3)被代理人
代码举例:
接口:
public interface women { public void doSomething(); }代理类:
public class OnePersonProxy implements women{private women on;public OnePersonProxy(){on= new OnePerson();}public void doSomething() { on.doSomething();}public women getOn() {return on;}public void setOn(women on) {this.on = on;}}真实类:
public class OnePerson implements women{public void doSomething() { System.out.println("onePerson do something");}}另一个对象调用:
public static void main(String[] args) {OnePersonProxy pro= new OnePersonProxy();pro.doSomething();}
其主要思想是,A与C之间的沟通,通过B进行。代理相当于“中介”,通过代理后,可以有些操作在代理端实现。
动态代理实现:
需要的主要类:
(1) Proxy类
Proxy类提供了用于创建动态代理类和实例对象的方法,它是所创建的动态代理类的父类,它最常用的方法如下:
- public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces):该方法用于返回一个Class类型的代理类,在参数中需要提供类加载器并需要指定代理的接口数组(与真实主题类的接口列表一致)。
- public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h):该方法用于返回一个动态创建的代理类的实例,方法中第一个参数loader表示代理类的类加载器,第二个参数interfaces表示代理类所实现的接口列表(与真实主题类的接口列表一致),第三个参数h表示所指派的调用处理程序类。
(2) InvocationHandler接口
InvocationHandler接口是代理处理程序类的实现接口,该接口作为代理实例的调用处理者的公共父类,每一个代理类的实例都可以提供一个相关的具体调用处理者(InvocationHandler接口的子类)。在该接口中声明了如下方法:
- public Object invoke(Objectproxy, Method method, Object[] args):该方法用于处理对代理类实例的方法调用并返回相应的结果,当一个代理实例中的业务方法被调用时将自动调用该方法。invoke()方法包含三个参数,其中第一个参数proxy表示代理类的实例,第二个参数method表示需要代理的方法,第三个参数args表示代理方法的参数数组。
动态代理类需要在运行时指定所代理真实主题类的接口,客户端在调用动态代理对象的方法时,调用请求会将请求自动转发给InvocationHandler对象的invoke()方法,由invoke()方法来实现对请求的统一处理。
package proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Calendar;import java.util.GregorianCalendar;public class DyProxy{public static void main(String args[]) {InvocationHandler handler = null;AbstractUserDAO userDAO = new UserDAO();<span style="background-color: rgb(255, 0, 0);">handler = new DAOLogHandler(userDAO);</span><span style="color:#FF0000;">AbstractUserDAO proxy = null;</span><span style="background-color: rgb(255, 0, 0);">(定义一个代理)</span>//动态创建代理对象,用于代理一个AbstractUserDAO类型的真实主题对象<span style="background-color: rgb(255, 0, 0);">(代理与实体对应上)</span>proxy = <span style="background-color: rgb(255, 0, 0);">(AbstractUserDAO)Proxy.newProxyInstance(AbstractUserDAO. class.getClassLoader(), new Class[]{AbstractUserDAO.class}, h</span>andler);<span style="color:#FF0000;">proxy.findUserById("张无忌"); //调用代理对象的业务方法</span><span style="background-color: rgb(204, 0, 0);">(代理执行方法,实质是实体方法执行)</span>System.out.println("------------------------------");AbstractDocumentDAO docDAO = new DocumentDAO();handler = new DAOLogHandler(docDAO);AbstractDocumentDAO proxy_new = null;//动态创建代理对象,用于代理一个AbstractDocumentDAO类型的真实主题对象proxy_new = (AbstractDocumentDAO)Proxy.newProxyInstance(AbstractDocumentDAO.class.getClassLoader(), new Class[]{AbstractDocumentDAO.class}, handler);proxy_new.deleteDocumentById("D002"); //调用代理对象的业务方法} }//抽象UserDAO:抽象主题角色interface AbstractUserDAO {public Boolean findUserById(String userId);}//抽象DocumentDAO:抽象主题角色interface AbstractDocumentDAO {public Boolean deleteDocumentById(String documentId);}//具体UserDAO类:真实主题角色class UserDAO implements AbstractUserDAO {public Boolean findUserById(String userId) {if (userId.equalsIgnoreCase("张无忌")) {System.out.println("查询ID为" + userId + "的用户信息成功!");return true;}else {System.out.println("查询ID为" + userId + "的用户信息失败!");return false;}}}//具体DocumentDAO类:真实主题角色class DocumentDAO implements AbstractDocumentDAO {public Boolean deleteDocumentById(String documentId) {if (documentId.equalsIgnoreCase("D001")) {System.out.println("删除ID为" + documentId + "的文档信息成功!");return true;}else {System.out.println("删除ID为" + documentId + "的文档信息失败!");return false;}}}//自定义请求处理程序类<span style="background-color: rgb(204, 0, 0);">(这个类需要通过代理调用,从而执行真实的方法)</span>class DAOLogHandler implements InvocationHandler {private Calendar calendar;private Object object;public DAOLogHandler() {} //自定义有参构造函数,用于注入一个需要提供代理的真实主题对象public DAOLogHandler(Object object) {this.object = object;}//实现invoke()方法,调用在真实主题类中定义的方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {beforeInvoke(); Object result = method.invoke(object, args); //转发调用 afterInvoke(); return null; } //记录方法调用时间 public void beforeInvoke(){ calendar = new GregorianCalendar(); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); String time = hour + ":" + minute + ":" + second; System.out.println("调用时间:" + time); } public void afterInvoke(){ System.out.println("方法调用结束!" ); }}
主要类:
0 0
- java设计模式-代理模式
- Java设计模式-----代理模式
- java设计模式-代理模式
- java设计模式---代理模式
- java设计模式---代理模式
- java设计模式---代理模式
- Java设计模式-代理模式
- Java 设计模式 代理模式
- Java设计模式-代理模式
- java设计模式-代理模式
- Java设计模式:代理模式
- java设计模式-----代理模式
- java 设计模式-代理模式
- java设计模式:代理模式
- java设计模式---代理模式
- java设计模式--代理模式
- java设计模式--代理模式
- java设计模式:代理模式
- android窗口的创建、显示、管理
- 针对用户阶段设计信息架构
- 面向对象设计原则
- 手机游戏留存时间短 社交因素影响新游戏选择
- 【2014/09/12】linux笔记 网络配置
- java设计模式---代理模式
- Wireshark抓包常见问题解析
- webdriver模拟操作鼠标、键盘事件
- 3、Android中Activity的跳转
- utf8 UTF-8等等各种区别
- 使用requirejs管理js
- oracle 多行转一列,一列转多行
- hdu 4035 Maze (树上的概率dp)
- fcntl使用