静态代理:

  真实角色和代理角色实现相同的接口,代理角色拥有真实角色的引用。代理角色去执行方法,对于某些“真正”需要真实角色自己执行的方法时,在代理角色内部就调用真实角色的方法,其他的就可以执行代理角色的方法(例如房主和中介,有带领客户看房,签合同,交钱,收房等方法,那么签合同、交钱就是“真正”需要真实角色自己执行的方法,其他的方法就可以直接交给中介去执行)

 应用场景:

1)安全代理:屏蔽对真实角色的直接访问

2)延迟加载:先加载轻量级的代理对象,真正需要时再加载真实对象

动态代理:

实现方式有:JDK自带的动态代理;    javaassist字节码操作库实现;CGUB;ASM

JDK自动的动态代理:

代码实现:

// 接口
public interface IAccount {
IAccount deposit(double money);
double getBalance();
}
// 真实角色
public class Account implements IAccount{
private double balance = 100;
@Override
public IAccount deposit(double money) {
balance += money;
return null;
}
@Override
public double getBalance() {
return balance;
} }
// 处理器
public class AccountHandler implements InvocationHandler{
IAccount account;
public AccountHandler(IAccount account) {
this.account = account;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("deposit".equals(method.getName())) {
method.invoke(account, args);
return proxy;
}else {
return method.invoke(account, args);
}
} }
// 应用
public class Client02 {
public static void main(String[] args) {
IAccount account = new Account();
AccountHandler handler = new AccountHandler(account);
IAccount proxy = (IAccount) Proxy.newProxyInstance(account.getClass().getClassLoader(), account.getClass().getInterfaces(), handler);
IAccount proxy1 = proxy.deposit(100);
double b = proxy.getBalance();
System.out.println(b);
}
}

结果:

可以看到在处理器那个代码里面,invoke()里面的两处的返回有些不同,一般的就直接一句代码:return method.invoke(account, args)

这里写这么多是为了体现 public Object invoke(Object proxy, Method method, Object[] args) 参数proxy 的作用:

取至源码(对invoke()方法的说明):

意思: 1:当一个方法在代理对象上被调用 will be(实际上是) 在 invocation handler上调用

2: method是在参数proxy 上被调用

proxy  <-------> this

// 将上面代码的应用部分改成:
public class Client02 {
public static void main(String[] args) {
IAccount account = new Account();
AccountHandler handler = new AccountHandler(account);
IAccount proxy = (IAccount) Proxy.newProxyInstance(account.getClass().getClassLoader(), account.getClass().getInterfaces(), handler);
proxy.deposit(100).deposit(200);
double b = proxy.getBalance();
System.out.println(b);
}
}

结果:

静态代理需要自定义代理对象,动态代理是动态生成代理对象

结构型模式 -- 代理模式(静态代理&动态代理)的更多相关文章

  1. 浅谈代理模式与java中的动态代理

    代理模式的定义: 代理模式是一个使用律非常高的模式,定义如下: 为其他对象提供一种代理,以控制对这个对象的访问. 类图: 简单的静态代理: public interface IRunner{ //这是 ...

  2. spring AOP 代理(静态与动态+使用cglib实现)

    一.没有代理模式 缺点: 1.工作量特别大,如果项目中有多个类,多个方法,则要修改多次. 2.违背了设计原则:开闭原则(OCP),对扩展开放,对修改关闭,而为了增加功能把每个方法都修改了,也不便于维护 ...

  3. 【结构型】Flyweight模式

    享元模式的主要目的.意图是为对象的大量使用提供一种共享机制.该模式的思想重在复用.共享复用.像文字.列表中的格子等这类多数都是需要考虑复用技术,否则必将大量耗费内存空间而使资源以及性能等大量耗费.该模 ...

  4. 浅谈Java代理二:Cglib动态代理-MethodInterceptor

    浅谈Java代理二:Cglib动态代理-MethodInterceptor CGLib动态代理特点: 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生 ...

  5. 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance

    浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...

  6. 代理模式与java中的动态代理

    前言    代理模式又分为静态代理与动态代理,其中动态代理是Java各大框架中运用的最为广泛的一种模式之一,下面就用简单的例子来说明静态代理与动态代理. 场景    李雷是一个唱片公司的大老板,很忙, ...

  7. 模式的秘密-代理模式(2)-JDK动态代理

    代理模式-动态代理 (1) (2) 代码实践动态代理: 第一步:被代理类的接口: package com.JdkProxy; public interface Moveable { void move ...

  8. 10分钟了解 代理模式与java中的动态代理

    前言    代理模式又分为静态代理与动态代理,其中动态代理是Java各大框架中运用的最为广泛的一种模式之一,下面就用简单的例子来说明静态代理与动态代理. 场景    李雷是一个唱片公司的大老板,很忙, ...

  9. java静态和动态代理原理

    一.代理概念 为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代.代理类负责请求的预处理.过滤.将请求分派给委托类 ...

  10. 【结构型】Proxy模式

    代理模式是指为其他对象提供代理来控制对象的访问.这种手段有时候可以给我们带来许多好处.如:通过代理可以实现异步响应处理:通过代理可以起到保护或限制对象的使用的作用,从而提高安全性. 在设计上,用户使用 ...

随机推荐

  1. 11.10 chkconfig:管理开机服务

    chkconfig 命令是Redhat系列的Linux系统中的系统服务管理工具,它可以用于查询和更新不同的运行等级下系统服务的启动状态. chkconfig命令的参数选项及说明 --list    显 ...

  2. 3.20 tr:替换或删除字符

    tr命令 从标准输入中替换.缩减或删除字符,并将结果写到标准输出. tr [option] [SET1]  [SET2] tr [选项]   [字符1]  [字符2]   -d    删除字符 -s  ...

  3. 《Java架构师的最佳实践》生产环境JVM调优之空间担保失败引起的FullGC

    1  问题现象 应用prod-xxx-k8s,在内存足够的情况下,仍然会产生偶发FullGC的问题. JVM配置如下: -Xmx8192m -Dhsf.server.max.poolsize=2500 ...

  4. iapp后台一本通php源码+iapp源码

    给大家分享一个后台源码,内有后台php源码,还有iapp对接源码,一本通 iapp+ PHP源码 经过一个小时的研究看看,测试了一下, 1.注册登录以修复正常,签到正常 2.所有工具正常 3.接口,i ...

  5. 在OpenShift平台上验证NVIDIA DGX系统的分布式多节点自动驾驶AI训练

    在OpenShift平台上验证NVIDIA DGX系统的分布式多节点自动驾驶AI训练 自动驾驶汽车的深度神经网络(DNN)开发是一项艰巨的工作.本文验证了DGX多节点,多GPU,分布式训练在DXC机器 ...

  6. JS使用Enter事件将输入的字符倒叙输出

    在JavaScript中执行当用户按下Enter键位时将用户输入的字符倒叙输出! HTML代码: <body> <form id="form1" runat=&q ...

  7. Python_Selenium之basepage 识别元素、浏览器操作、获取属性、鼠标事件、键盘事件、弹窗、切换frame、切换句柄等封装

    #coding=gbkimport osimport timefrom selenium import webdriverfrom selenium.webdriver.common.by impor ...

  8. mongodb的ObjectId最后三个字节有趣的地方

    ObjectId 由12个字节组成,其中组成如下: a 4-byte timestamp value, representing the ObjectId's creation, measured i ...

  9. 狂神说JUC学习笔记(一)

    狂神说JUC的原版笔记: 链接:https://pan.baidu.com/s/12zrGI4JyZhmkQh0cqEO4BA 提取码:d65c 我的笔记在狂神的笔记上增加了一些知识点或者做了些许修改 ...

  10. 错误:软件包:php-fpm-5.4.16-42.el7.x86_64 需要:php-common(x86-64)

    报错信息:错误:软件包:php-fpm-5.4.16-42.el7.x86_64 (/php-fpm-5.4.16-42.el7.x86_64)需要:php-common(x86-64) = 5.4. ...