Java 代理模式

代理分为静态代理与动态代理。我按功能将代理的组成类分为:标的类、标的接口、拦截类、耦合类

下面以具本代码举例说明。

一、静态与动态代理的公共部分

package proxy.common;


/**
 * 
 * 
 *  AngelSoftware, Inc.
 *  Copyright (C): 2008
 * 
 *  Description:
 *   TODO 标的类
 *   
 *  Revision History:
 *  Jun 5, 2008 fity.wang		initial version.
 * 
 * 
*/ public class TargetImpl implements Target1, Target2 { public void doSomething() { System.out.println("doSomething!"); } public String do1(String msg) { // TODO Auto-generated method stub System.out.println("do1: " + msg); return "this is String Mehtod!"; } public int do2() { System.out.println("do2!"); return 1000; } } package proxy.common; /** * *
 *  AngelSoftware, Inc.
 *  Copyright (C): 2008
 * 
 *  Description:
 *   TODO 标的接口
 *   
 *  Revision History:
 *  Jun 5, 2008 fity.wang		initial version.
 * 
 * 
*/ public interface Target1 { void doSomething(); } package proxy.common; /** * *
 *  AngelSoftware, Inc.
 *  Copyright (C): 2008
 * 
 *  Description:
 *   TODO 标的接口
 *   
 *  Revision History:
 *  Jun 5, 2008 fity.wang		initial version.
 * 
 * 
*/ public interface Target2 { String do1(String msg); int do2(); } package proxy.common; /** * *
 *  AngelSoftware, Inc.
 *  Copyright (C): 2008
 * 
 *  Description:
 *   TODO 拦载类
 *   
 *  Revision History:
 *  Jun 5, 2008 fity.wang		initial version.
 * 
 * 
*/ public class Intercept { public void before() { System.out.println("Before……"); } public void after() { System.out.println("After."); } }
二静态代理特征部分
package proxy.jingtai;

import proxy.common.Intercept;
import proxy.common.TargetImpl;
/**
 * 
 * 
 *  AngelSoftware, Inc.
 *  Copyright (C): 2008
 * 
 *  Description:
 *   TODO 耦合类(耦合是为了解耦)
 *   
 *  Revision History:
 *  Jun 5, 2008 fity.wang		initial version.
 * 
 * 
*/ public class Invocation { public Object invokeDoSomething() { TargetImpl t = new TargetImpl(); Intercept p = new Intercept(); //调用真实的标的类的方法之前置入拦载类的方法 p.before(); //调用真实的标的类的方法 t.doSomething(); //调用真实的标的类的方法之后置入拦载类的方法 p.after(); return null; } } package proxy.jingtai; /** * *
 *  AngelSoftware, Inc.
 *  Copyright (C): 2008
 * 
 *  Description:
 *   TODO 静态代理(这理只简单地讲一下,着重讲动态代理)
 *   
 *  Revision History:
 *  Jun 5, 2008 fity.wang		initial version.
 * 
 * 
*/ public class Test { public static void main(String args[]) { new Invocation().invokeDoSomething(); } }
三、动态代理特征部分
package proxy.dongtai;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import proxy.common.Intercept;
import proxy.common.TargetImpl;
/**
 * 
 * 
 *  AngelSoftware, Inc.
 *  Copyright (C): 2008
 * 
 *  Description:
 *   TODO 耦合类(耦合是为了解耦)
 *   
 *  Revision History:
 *  Jun 5, 2008 fity.wang		initial version.
 * 
 * 
*/ public class Invocation implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { TargetImpl t = new TargetImpl(); Intercept p = new Intercept(); if (args!=null&&args.length ==1) { //更改参数 args[0] = "param value has changed"; } //调用真实的标的类的方法之前置入拦载类的方法 p.before(); //调用真实的标的类的方法 Object o = method.invoke(t, args); //调用真实的标的类的方法之后置入拦载类的方法 p.after(); return o; } } package proxy.dongtai; import proxy.common.Target1; import proxy.common.Target2; /** * *
 *  AngelSoftware, Inc.
 *  Copyright (C): 2008
 * 
 *  Description:
 *   TODO 测试类
 *   
 *  Revision History:
 *  Jun 5, 2008 fity.wang		initial version.
 * 
 * 
*/ public class Test { /** * logic1与logic的共同逻辑 * @param proxy 代理 */ private static void publicLogic(Object proxy) { //对目标接口Target1代理的调用 System.out.println("对目标接口Target1代理的调用"); Target1 t1 = (Target1)proxy; t1.doSomething(); System.out.println(); //对目标接口Target2的调用 System.out.println("对目标接口Target2代理的调用"); Target2 t2 = (Target2)proxy; System.out.println("Target Mehod do1 return: " + t2.do1("hello!")); System.out.println("Target Mehod do2 return: " + t2.do2()); System.out.println(); System.out.println(); } /** * new Class[]{Target2.class,Target1.class} * 正常 * @return */ public static void logic1() { Invocation iv = new Invocation(); /* * Proxy.newProxyInstance的参数说明 * 参数1:类加载器(个人感觉这个参数有点多佘,这个参数完成可以去掉,不知当初他们为何要设这个参数干么) * 参数2:代理的标的接口.就是说,你要代理的标的类可能会实现多个接口,你可以有选择性地代理这些接口 * 参数3:InvocationHandler的实现类.InvocationHandler接口做用就是解耦,解开标的类与拦载类之间的耦合,使它们之间可以互不关心 */ Object proxy = java.lang.reflect.Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{Target2.class,Target1.class}, iv); publicLogic(proxy); } /** * new Class[]{Target1.class} * 将会出异常,因为他没有在参数中声时自己要调用Target2接口,而后面却又去调用 * @return */ public static void logic2() { Invocation iv = new Invocation(); /* * Proxy.newProxyInstance的参数说明 * 参数1:类加载器(个人感觉这个参数有点多佘,这个参数完成可以去掉,不知当初他们为何要设这个参数干么) * 参数2:代理的标的接口.就是说,你要代理的标的类可能会实现多个接口,你可以有选择性地代理这些接口 * 参数3:InvocationHandler的实现类.InvocationHandler接口做用就是解耦,解开标的类与拦载类之间的耦合,使它们之间可以互不关心 */ Object proxy = java.lang.reflect.Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{Target1.class}, iv); publicLogic(proxy); } public static void main(String args[]) { logic1(); logic2(); } }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java代理模式是一种结构型设计模式,其目的是为其他对象提供一种代理以控制对这个对象的访问。代理对象可以在客户端和目标对象之间充当中介,以便于客户端访问目标对象时,可以在不改变目标对象的情况下添加一些额外的功能,比如安全性、远程访问、缓存等。 在Java中,代理模式可以通过两种方式实现:静态代理和动态代理。静态代理需要手动编写代理类,而动态代理可以在运行时通过反射机制动态生成代理类,更加灵活。 举个例子,假设我们有一个接口`Subject`,其中定义了一些方法。我们希望在调用这些方法时,增加一些额外的日志记录功能。我们可以编写一个代理类`SubjectProxy`,在代理类中实现接口方法并调用目标对象的方法,同时在方法前后添加日志记录的代码。客户端则通过代理类访问目标对象。 静态代理示例代码如下: ```java public interface Subject { void doSomething(); } public class RealSubject implements Subject { @Override public void doSomething() { System.out.println("RealSubject do something."); } } public class SubjectProxy implements Subject { private Subject realSubject; public SubjectProxy(Subject realSubject) { this.realSubject = realSubject; } @Override public void doSomething() { System.out.println("Before do something."); realSubject.doSomething(); System.out.println("After do something."); } } public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); Subject subjectProxy = new SubjectProxy(realSubject); subjectProxy.doSomething(); } } ``` 动态代理示例代码如下: ```java public class SubjectHandler implements InvocationHandler { private Object target; public SubjectHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before " + method.getName()); Object result = method.invoke(target, args); System.out.println("After " + method.getName()); return result; } } public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); InvocationHandler handler = new SubjectHandler(realSubject); Subject subjectProxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler); subjectProxy.doSomething(); } } ``` 无论是静态代理还是动态代理,代理模式都可以在不改变目标对象的情况下,为其添加额外的功能,提高代码的可复用性和灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值