• 学无止境 Java工程师的进阶之旅

目录

  • 一、什么是代理
  • 二、作用
  • 三、静态代理
    • 3.1、简介
    • 3.2、实现步骤
    • 3.3、缺点
  • 四、动态代理
    • 4.1、概念
    • 4.2、分类
      • 4.2.1、JDK动态代理
      • 4.2.2、CGLIB动态代理
    • 4.3、回顾Method类
    • 4.4.、反射包
    • 4.5、实现步骤
      • 4.5.1、实现中间商赚差价
      • 4.5.2、实现执行方法前后打印日志和执行事务

一、什么是代理

你想买件东西,但是直接去厂家厂家是不卖的,你可以在淘宝京东等购物商城购买,商家此时便充当代理的角色

专业点来讲:

为其他对象提供一种代理以控制对这个对象的访问,在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在两者种起到中介的作用
A无法访问C,B可以访问C,A可以通过调用B调用C,此时B是C的代理


二、作用

  • 功能增强:增加额外的功能,如日志记录,事务(主要使用)
  • 控制访问:代理类不让你访问目标类,如商家不让用户访问厂家

三、静态代理

3.1、简介

代理类手动创建,代理目标确定,实现简单,容易理解

3.2、实现步骤

需求:模拟用户从淘宝购买iphone,假设苹果工厂不单独卖给用户

用户:客户类
商家:代理
厂家:目标类

用户——》商家——》厂家

实现步骤

  • 创建一个接口IphoneSell,定义卖iphone的方法sell,表示厂家和商家的行为
  • 创建商家类TaoBao和厂家类AppleFactory,实现接口
  • 创建客户类,调用商家的方法购买

IphoneSell接口

public interface IphoneSell {float sell(int amount);
}

厂家类AppleFactory

package com.proxy.factory;import com.proxy.service.IphoneSell;public class AppleFactory implements IphoneSell {@Overridepublic float sell(int amount) {return 3299.0f;}
}

商家类TaoBao

package com.proxy.business;import com.proxy.service.IphoneSell;
import com.proxy.factory.AppleFactory;public class TaoBao implements IphoneSell {private AppleFactory factory = new AppleFactory();@Overridepublic float sell(int amount) {//销售时商家向厂家发送订单,厂家发货float price = factory.sell(amount);//加价销售  增强功能return price + 700;}
}

main方法

package com.proxy;import com.proxy.business.TaoBao;public class ShopMain {public static void main(String[] args) {TaoBao taoBao = new TaoBao();float prcie = taoBao.sell(1);System.out.println(prcie);}
}

3.3、缺点

目标类增加,代理类成倍增加,接口修改所有实现类都得修改


四、动态代理

4.1、概念

程序执行时,使用jdk反射机制,创建代理类对象,并动态的指定要代理的目标类

4.2、分类

4.2.1、JDK动态代理

  • 使用JDK的Proxy实现代理
  • 反射包java.lang.reflect,三个类InvocationHandler,Method,Proxy
  • 要求目标类与代理类实现相同的接口
  • 若目标类不存在接口无法使用该方式(使用CGLIB)

4.2.2、CGLIB动态代理

  • 第三方的工具库,创建代理对象
  • 生成目标类的子类,子类是增强过的,也就是代理对象,所有需要要求目标类能被继承,且不能final

4.3、回顾Method类

public interface HelloService {void sayHello(String name);}
public class HelloServiceImpl implements HelloService {@Overridepublic void sayHello(String name) {System.out.println("hello" + name);}
}
public class TestApp {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {HelloService target = new HelloServiceImpl();//getMethod("方法名","方法参数数据类型")Method method = HelloService.class.getMethod("sayHello", String.class);/*** 表示执行方法的调用* invoke(对象,方法执行参数)*/method.invoke(target, ":jiali");  //hello:jiali}
}

4.4.、反射包

代理类完成的功能:调用目标方法且增强功能
1、InvocationHandler接口:就一个方法invoke():表示代理对象要执行的功能代码

//Object proxy:jdk创建的代理对象,无需赋值
//Method method:目标类中的方法,jdk提供method对象
//Object[] args:目标类中的方法的参数,jdk提供的
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;

2、Proxy类:不需要手动new对象,使用Proxy类的方法newProxyInstance()创建并返回代理对象

//ClassLoader 类加载器 a.getClass().getClassLoader()
//Class<?>[]  接口,目标类实现的接口,也是反射获取的
//InvocationHandler 代理类要完成的功能
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException {}

3、Method类:表示目标类中的方法,通过Method可以执行某个目标类的方法Method.invoke(目标对象,方法参数)

4.5、实现步骤

4.5.1、实现中间商赚差价

1、定义行为

public interface UsbSell {float sell(int amount);
}

2、定义目标类

public class UsbFactory implements UsbSell {@Overridepublic float sell(int amount) {return 100.0f;}
}

3、定义MySellHandler实现invocationHandler

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class MySellHandler implements InvocationHandler {private Object target = null;//传入需要被代理的目标对象public MySellHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;//表示执行目标对象的方法的调用invoke(目标类,方法参数)result = method.invoke(target, args);//增强功能if (result != null) {Float price = (Float) result;price = price + 25;result = price;}//增强后的价格return result;}
}

4、测试

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;public class MainShop {public static void main(String[] args) {//创建目标对象IphoneSell factory = new AppleFactory();//将目标对象交给InvocationHandlerInvocationHandler handler = new MySellHandler(factory);//创建代理对象实现功能增强UsbSell proxyInstance = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),factory.getClass().getInterfaces(),handler);System.out.println(proxyInstance.sell(1));//125.0}
}

4.5.2、实现执行方法前后打印日志和执行事务

public interface MyService {void doSome();
}
public class MyServiceImpl implements MyService {@Overridepublic void doSome() {System.out.println("执行业务方法");}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class MyHandler implements InvocationHandler {Object target;public MyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//打印日志System.out.println("打印日志成功");//执行目标方法method.invoke(target, args);//提交事务System.out.println("提交事务成功");return null;}
}
public class Test {public static void main(String[] args) {MyService myService = new MyServiceImpl();InvocationHandler myHandler = new MyHandler(myService);MyService proxyInstance = (MyService) Proxy.newProxyInstance(myService.getClass().getClassLoader(), myService.getClass().getInterfaces(), myHandler);proxyInstance.doSome();}
}


23种设计模式——代理模式相关推荐

  1. 23种设计模式----------代理模式(一)

    代理模式也叫委托模式. 代理模式定义:对其他对象提供一种代理从而控制对这个对象的访问.就是,代理类 代理 被代理类,来执行被代理类里的方法. 一般情况下,代理模式化有三个角色. 1,抽象的主题类(或者 ...

  2. 23种设计模式-代理模式《中介公司》

    对于许久不用的东西,容易忘记.百度许久,也未能找到自己所要. 从今日起,有些东西就记载下来,不仅方便自己,希望能帮到他人吧 一个人避免不了与中介打交道,比如租房,你很少会遇上房东,而是所谓的二房东,等 ...

  3. 23种设计模式——桥接模式

    文章目录 23种设计模式--桥接模式 1.桥接模式概述 2.桥接模式结构 3.桥接模式的实现 4.桥接模式的注意事项和细节 23种设计模式--桥接模式 1.桥接模式概述 桥接模式介绍 桥接(Bridg ...

  4. 23种设计模式-工厂模式

    23种设计模式-工厂模式 前言: [我们为什么需要使用工厂模式?] /*** 在使用工厂模式之前,我们要创建 实现了相同接口的对象 都需要直接new(),如下* */@Testpublic void ...

  5. 23种设计模式——工厂模式

    文章目录 23种设计模式--工厂模式 1.工厂模式概述 2.简单工厂模式 2.1.简单工厂模式的优缺点 2.2.简单工厂模式的结构 2.3.简单工厂模式的实现 3.工厂方法模式 3.1.工厂方法模式的 ...

  6. 23种设计模式常用模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用.设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人员经过 ...

  7. SSM源码分析之23种设计模式(策略模式和模板模式)

    23种设计模式之策略模式和模板模式 目录 策略模式使用场景 策略模式实现 模板模式 目录 策略模式使用场景 策略模式:根据用户的需求处理数据时候需要对算法做出选择,固定的一些算法(不再发生变化的算法) ...

  8. 23种设计模式----模板方法模式----行为模式

    模板方法模式 1.模板方法模式是什么 2.模板方法的组成 3.模板方法中不同的类的行为 4.例子 4.1 例子的背景 4.2模板类--父亲寻找继承人的方式 4.3实现类----孩子类 4.4测试类-- ...

  9. 23种设计模式----原型模式----创建型模式

    原型模式 1.1什么是原型模式 1.2为什么要使用原型模式 2.原型模式的解释 3.例子 3.1例子将要实现的目标 3.2例子设计 3.3原型类 3.4具体实现的3个原型实例类 3.5管理类 3.6工 ...

最新文章

  1. linux 明文创建密码,linux下抓取内存中明文密码mimipenguin
  2. DeepMind提出「心智神经网络ToMnet」,训练机器的「理解」能力
  3. Android--Genymotion虚拟机(模拟器)的配置
  4. 中国超细旦丝现状调研及投资前景评估报告2022-2028年版
  5. WinCE驱动调试助手V2.5
  6. 关于 std::set/std::map 的几个为什么
  7. ISLR—第二章 Statistical Learning
  8. python中文字体下载_python中matlabplot和seaborn中文字体显示的一种解决方案
  9. RedHat 6 创建和扩容LVM卷
  10. Windows下如何远程连接Linux图形化桌面-教你两招
  11. Dubbo + Zookeeper 简单搭建
  12. 泰坦尼克号数据_kaggle泰坦尼克号之Python手把手数据分析
  13. RGB网页颜色在线取色器
  14. 踩坑合集(1)——虚拟机桥接模式下的连网问题
  15. office精英俱乐部_开放组织读书俱乐部:收回精英制
  16. Python学习之学校教学(辨别身份证的真伪,并判断性别)
  17. python sdk是什么意思_什么是 SDK?
  18. 快速集成百度定位功能
  19. 游戏安全逆向工程师:从入门到精通83课分享
  20. Chpater2.3 执行AD HOC命令

热门文章

  1. 【调剂】985东南大学2020年苏州联合研究生院相关专业调剂信息
  2. 深度学习绘图模板.pptx
  3. C++ 面向对象 - 类的多态性与虚函数
  4. 《黑客帝国》或颠倒的两面
  5. Sentinel Dashboard轻松流控
  6. linux火狐弹出框乱码,Linux系统下火狐浏览器页面出现乱码怎么办?
  7. 165体重_女生165cm标准体重
  8. MIT-BIH心律失常数据库目录(译)
  9. RGB颜色空间转LAB
  10. hdl_localization试读