设计模式(八)代理模式(Proxy)

Proxy 代理模式:解耦

日常开发中的日志、权限、事务处理等。

实现原理:

代理模式实现原理图

代理模式

代理模式:是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 按照代理的创建时期,代理类可以分为两种。 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 动态代理:在程序运行时,运用反射机制动态创建而成。

静态代理模式如下:

1.抽象目标类

(){();}

2.具体目标类

(){(){};}

3.代理类

(){private RealSubject realSubject;(){/**附加逻辑**/realSubject.Request();/**附加逻辑**/};}动态代理: JDK动态代理

JDK动态的代理的3个主要类: Proxy:代理类 InvocationHandler: 接口 Method:要被调用的方法 TaxInterface.java

{();}

Tax.java

{() {System.out.println(“进行所得税计算的逻辑处理”);}}

TimeProxy.java

{private Object obj;//绑定代理对象public Object bind(Object obj){this.obj = obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);}Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object result = null;try {long startTime = System.nanoTime();result = method.invoke(obj, args);long endTime = System.nanoTime();System.out.println(“计算程序运行时间 :” +(endTime-startTime));} catch (Exception e) {e.printStackTrace();}return result;}}

客户端测试:Client.java

{(String[] args) {TimeProxy timeProxy = new TimeProxy();TaxInterface taxInterface = (TaxInterface)timeProxy.bind(new Tax());taxInterface.doTax();}}

JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。

Cglib动态代理

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。 示例如下: BookFacadeCglib.java

package com.ldw.dao; {(); }

BookCadeImpl1.java

package com.ldw.dao.impl;/** * 这个是没有实现接口的实现类 * * @author csu.ldw * */ {() {System.out.println(“增加图书的普通方法…”);} }

BookFacadeProxy.java

package com.ldw.proxy;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;/** * 使用cglib动态代理 * * @author student * */ {private Object target;/*** 创建代理对象** @param target* @return*/public Object getInstance(Object target) {this.target = target;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(this.target.getClass());// 回调方法 enhancer.setCallback(this);// 创建代理对象 return enhancer.create();}Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {System.out.println(“事物开始”);proxy.invokeSuper(obj, args);System.out.println(“事物结束”);return null;}}

TestCglib.java

package com.ldw.test; import net.battier.dao.impl.BookFacadeImpl1; import net.battier.proxy.BookFacadeCglib; {(String[] args) {BookFacadeCglib cglib=new BookFacadeCglib();BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());bookCglib.addBook();} } 应用

SpringAOP、Struts拦截器、日志管理等。

附加

struts2的拦截器属于AOP思想,采用了代理模式

struts2中,最重要的一个类是org.apache.struts2.dispatcher.FilterDispatcher用户通过浏览器提交一个HttpServletRequest请求后,请求被在web.xml中的过滤器FilterDispatcher拦截在FilterDispatcher过滤器中首先询问ActionMapper是否需要调用某个Action来处理请求,如果ActionMapper决定需要调用某个请求,FilterDispatcher则把请求的处理交给ActionProxy,ActionProxy通过配置文件struts.xml找到需要调用的Action类,然后ActionProxy创建一个ActionInvocation实例并通用该Action但在调用之前,ActionInvocation会根据配置加载Action相关的Intercepter,等Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的Result结果。

一个人最大的破产是绝望,最大的资产是希望。

设计模式(八)代理模式(Proxy)

相关文章:

你感兴趣的文章:

标签云: