Proxy代理模式
来源:互联网 发布:淘宝上好的cos店 编辑:程序博客网 时间:2024/05/17 03:28
Proxy Pattern(即:代理模式),23种常用的面向对象软件的设计模式之一
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
优点:
- 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
- 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。
- 高扩展性
一个是真正的你要访问的对象(目标类),另一个是代理对象,真正对象与代理
对象实现同一个接口,先访问代理类再访问真正要访问的对象。
代理模式的要求:
- 代理这和被代理这实现相同的接口
- 代理者必须有被代理这的实例(引用)
- 代理这调用被代理这的方法
静态代理:简单代理
代理者和被代理这需要是实现共同的接口,即我们的装饰模式
创建一个潘金莲对象,实现Kindweman接口,同时创建一个代理者王婆也实现这个接口
public class PJL implements KindWeman{ @Override public void ShowEyes(Double money) { System.out.println("PJL 拿到"+money+"元钱,showeyes"); } @Override public void DoSe(Double money) { System.out.println("PJL 拿到"+money+"元钱,Dose"); }}
public class WP implements KindWeman { private KindWeman kw = null; public WP(KindWeman kw ){ this.kw = kw; } @Override public void ShowEyes(Double money) { kw.ShowEyes(money); } @Override public void DoSe(Double money) { kw.DoSe(money); }}
潘金莲需要王婆的代理,代理者调用的方法都是被代理者的
public static void main(String[] args){ KindWeman KW = new PJL(); WP p = new WP(KW); p.ShowEyes(3.0); p.DoSe(6.0); }
动态代理
动态代理它可以直接给某一个目标对象生成一个代理对象,而不需要代理类存在。
动态代理与代理模式原理是一样的,只是它没有具体的代理类,直接通过反射生成了一个代理对象。
动态代理生成技术:
1、jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象。
2、cglib (spring框架)
Java.lang.reflect.Proxy类可以直接生成一个代理对象,看例子,这里不需要王婆这个代理者,jdk给我们提供了。
@Testpublic void test(){ KindWeman kw = new PJL(); //创建一个代理对象 //ClassLoader:类加载器。固定写法,和被代理类使用相同的类加载器即可。kw.getClass().getClassLoader() //Class[] interface:代理类要实现的接口。固定写法,和被代理类使用相同的接口即可。kw.getClass().getInterfaces() //InvocationHandler:策略(方案)设计模式的应用。如何代理?即代理的过程,你需要的操作 KindWeman KWproxy = (KindWeman) Proxy.newProxyInstance(kw.getClass().getClassLoader(), kw.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //nvocationHandler中的invoke方法:调用代理类的任何方法,此方法都会执行 //Object proxy:代理对象本身的引用。一般用不着。 //Method method:当前调用的方法。通过反射, KWproxy调用誰,这里的Method就是谁 //Object[] args:当前方法用到的参数 System.out.println("我是中间代理:需要收取费用"); Object o = method.invoke(kw, new Object[]{(Double) args[0] / 2}); System.out.println("事务完成,下次再来!"); return o; } }); KWproxy.ShowEyes(6.0); KWproxy.ShowEyes(3.0);}
使用这个思想,在我们前面讲到的业务层调用ThreadLocal管理,就不必要在servce层面上编写了。编写一个类来动态的获取服务,然后在代理当中添加ThreadLocal类实现事务的功能
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import com.itheima.service.AccountService;import com.itheima.service.impl.AccountServiceImpl;public class ObjectFactory { //方法返回一个代理对象 public static AccountService getAccountService(){ final AccountService as= new AccountServiceImpl(); AccountService proxy = (AccountService) Proxy.newProxyInstance(as.getClass().getClassLoader(), as.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object invoke = null; try { ManagerThreadLocal.startTransacation();//begin //执行的是真实对象的转账方法 invoke = method.invoke(as, args); ManagerThreadLocal.commit();//提交事务 } catch (Exception e) { try { ManagerThreadLocal.rollback();//回滚事务 } catch (Exception e1) { e1.printStackTrace(); } }finally{ try { ManagerThreadLocal.close(); } catch (Exception e) { e.printStackTrace(); }//关闭 } return invoke; } }); return proxy; }}
public void transfer(String fromname, String toname, double money) throws Exception { // ad.updateAccount(fromname, toname, money); AccountDao ad = new AccountDaoImpl(); //分别得到转出和转入账户对象 Account fromAccount = ad.findAccountByName(fromname); Account toAccount = ad.findAccountByName(toname); //修改账户各自的金额 fromAccount.setMoney(fromAccount.getMoney()-money); toAccount.setMoney(toAccount.getMoney()+money); //完成转账操作 ad.updateAccout(fromAccount); int i = 10/0; ad.updateAccout(toAccount); }
0 0
- Proxy模式 代理模式
- 代理模式:Proxy模式
- 代理(Proxy)模式
- 代理模式Proxy Design
- 代理(Proxy)模式
- 代理(Proxy)模式
- 代理模式(Proxy Pattern)
- 代理(Proxy)模式
- 代理模式(Proxy Pattern)
- proxy(代理)模式
- Proxy Pattern (代理模式)
- Proxy pattern 代理模式
- 代理模式(Proxy)
- java 代理(proxy)模式
- Proxy 代理模式
- 代理模式(Proxy)
- 代理模式(Proxy pattern)
- Proxy(代理)模式
- linux uname命令
- 量化交易
- 遍历出指定目录下的所有文件 --递归调用
- Linux 系统(RetHat6.0)下DHCP服务器的配置
- Apache的下载安装(主要说的 64位)及问题
- Proxy代理模式
- 光伏电站综合自动化
- jzoj 4833. 【NOIP2016提高A组集训第3场10.31】Mahjong dfs+暴力
- xz_wrapper.c:28:18: 致命错误:lzma.h:没有那个文件或目录 解决案例
- hdu 5900 QSC and Master(acm/icpc沈阳网络赛,区间DP)
- js 根据节点增加ul列表li内容
- opengl:你不知道的左右手坐标系
- 重写equals方法
- 教育类剧集:《女王的教室》