《java设计模式之代理模式.docx》由会员分享,可在线阅读,更多相关《java设计模式之代理模式.docx(5页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、代理模式代理模式即ProxyPattern,什么是代理模式呢?即对其他对象提供一种代理以控制对这个对象的访问。例如,我们有一个类不想被其他类直接调用,我们怎么办呢?我们只能通过代理的形式,让其他的类来调用代理类,代理类必须和目标类是用的同一个方法,且代理类的方法可以在目标类的基础上进行功能扩展,形式如下:目标类:class Personvoid saysyso(hello);代理类:class PersonProxyvoid say start timePerson.say();end time代理的架构图如下:面向方面编程AOP什么是AOP(Aspect oriented program)呢
2、?系统中存在交叉业务,一个交叉业务就是要切入到系统中的一个方面。交叉业务即安全,事务,日志等功能贯穿到好多个模块中。即它的重要原则是,不要把供货商暴露给你的客户。AOP的目标就是要使交叉业务模块化。AOP即代理类在目标类的方法的周围放上一些安全,事物,日志,我们能实现和目标类一样的功能。动态代理技术什么是动态代理呢?即JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类注意:JVM生成的动态类必须实现一个或多个接口,所以Jvm生成的动态类只能用作具有相同接口的目标类的代理代理类的各个方法通常除了要调用目标的相应的方法对外返回目标的结果外,还可以在代理方法中的四
3、个位置加上系统的功能代码:a) 在调用目标方法之前、b) 在调用目标方法之后c) 在调用目标方法的前后都有d) 在处理目标方法异常的catch块中总结:即:当我们代理类想去代理一个目标类的时候,我们通过什么方式来知道目标类的方法呢?我们只能让要被代理的目标类继承一个或多个接口,这些接口的方法,目标类并继承了这些方法。代理类也必须继承目标类所继承的接口,即也必须实现了接口的的方法,而且我们在实现接口方法的同时可以在周围加上安全,事物,日志等扩展功能。当我目标类没有继承接口,我们只能通过CGLIB库动态的生成一个类的子类,一个类的子类也可以作为一个代理类。我们通常在写代理常用的方法.代理类为Pro
4、xy。a) static Class getProxyClass(ClassLoader loader, Class. interfaces):返回代理类的 java.lang.Class 对象,并向其提供类加载器和接口数组。b) static Object newProxyInstance(ClassLoader loader, Class interfaces, InvocationHandler h):返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。我们根据方法,总共有两种方式:第一种:public class ProxyTest2 public static
5、 void main(String args) throws ExceptionClass clazzProxy=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);Constructor consclazz=clazzProxy.getConstructor(InvocationHandler.class);class MyInvocationHandler implements InvocationHandlerArrayList target=new ArrayList();Overridepu
6、blic Object invoke(Object proxy, Method method, Object args)throws Throwable Object retVal=method.invoke(target, args);return retVal;Collection coll=(Collection)consclazz.newInstance(new MyInvocationHandler();coll.add(haha);coll.add(heihei);System.out.println(coll.size();第二种:public class ProxyTest3
7、public static void main(String args) Collection coll=(Collection) Proxy.newProxyInstance(Collection.class.getClassLoader(),new ClassCollection.class,new InvocationHandler() ArrayList target=new ArrayList();public Object invoke(Object proxy, Method method, Object args)throws Throwable long begin=Syst
8、em.currentTimeMillis();Object retVal=method.invoke(target, args);Thread.sleep(100);long end=System.currentTimeMillis();System.out.println(method+running of time:+(end-begin);return retVal;);coll.add(haha);coll.add(heihei);System.out.println(coll.size();我们看到以上两个代码都是已经指定好了目标类ArrayList,我们在实际开发中就不能这样了,因
9、为那样没有灵活性。,我们可以写个方法是getProxy()来绑定接受目标同时返回代理对象,让调用者更方便,甚至不用接触任何代理的API。那么我们怎么做呢?我们把系统功能代码模块化,即将切面代码改为通过参数形式提供我们将上面第二种方式改为具有灵活性的代码首先我们先定义一个接口,并让一个类去实现这个接口。/需要实现的接口public interface Advice public void startMethod(Method method);public void endMethod(Method method);/我们让一个类去实现这接口public class MyAdvice implem
10、ents Advice private long begin=0;private long end=0;Overridepublic void startMethod(Method method) begin=System.currentTimeMillis();Overridepublic void endMethod(Method method) end=System.currentTimeMillis();System.out.println(method+running of time:+(end-begin);public class ProxyTest3 public static
11、 void main(String args) final ArrayList target=new ArrayList();Collection coll = (Collection) getProxy(target,new MyAdvice();coll.add(haha);coll.add(heihei);System.out.println(coll.size();/传入两个参数,一个是目标类,一个是日志,即adviceprivate static Object getProxy(final Object target,final Advice advice) Object coll=
12、Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() public Object invoke(Object proxy, Method method, Object args)throws Throwable advice.startMethod(method);Object retVal=method.invoke(target, args);Thread.sleep(100);advice.endMethod(method);return retVal;);return coll;