文章目录

  • 先举一个例子:
  • 开闭原则
  • 什么是代理
  • 两种调用的方式:
  • 代理定义:
  • 代理的实现方式
  • 静态代理
  • 代理的目的:
  • 如何让程序知道要增强的功能是谁?
  • 静态代理缺点:
  • 动态代理
  • 什么是动态代理
  • 动态代理的实现
  • 静态代理和动态代理的区别
  • 静态代理:
  • 动态代理:



——————————————————————————————

先举一个例子:

有一个转账的类:

public class 转账{
    public void 转账 (int num,String A,String B){
        System.out.println(A+"给"+B+"转账"+num);
    }
}

**转账操作:**转账之前需要验证A和B的身份,转账操作、转账之后需要对数据库金额进行改变
将上面三个逻辑写在一个方法当中是不可行的——》在实践过程当中,最好只能对应一个逻辑——》1.调用验证方法 2.调用转账方法 3.操作数据库
为什么实践过程中,一个方法最好只能对应一个逻辑??
——》原因:方法的使用:如果一个方法当中对应这多个逻辑,那么会造成该方法的冗余,一旦条件发生变动,那么对于该方法的改变工程量巨大

开闭原则

例:登录

ideamaven银行转账 转账java_ideamaven银行转账


如果要新加一个 功能:判断权限(区分管理员和数据库)

-----!!!重新写代码是不可以的(不能在原有的代码基础上进行改变)

原因:违反了程序的设计原则(设计原则【开闭原则】:一个方法对应一个逻辑,已经写好的代码不能进行改变,原因在于调用该方法的代码可能有很多 ,一旦进行改动,那么就会牵一发而动全身)

【开闭原则:程序对访问开放,对修改关闭】

ideamaven银行转账 转账java_目标对象_02


------可行的方法:

新写代码:写新的类,验证的servlet让用户进行调用

调用的逻辑:调用验证servlet——>调用LoginServlet

什么是代理

代理类控制着对目标类的访问

ideamaven银行转账 转账java_动态代理_03


在代理当中,login当中的登录方法是不会被直接调用的

两种调用的方式:

第一种,传统的方式,调用登录方法,再进行验证

第二种,直接插入进去,调用方法的时候,验证也就进行了

实际当中用的第二种方式比较多,因为第一种方式比较冗余

ideamaven银行转账 转账java_动态代理_04

代理定义:

代理定义: 给目标对象提供一个代理对象,并且由 目标对象 控制着对 代理对象 的引用

在传统的方法当中 ——登陆对象和验证对象是相互独立的,从下边的实际案例当中可以看出一个问题,就是用户可以只进行验证不进行登录,或只进行登录不进行验证

在代理方式中 ——在 代理验证 对象当中有loginServlet,我们在调用代理验证对象的login()方法,就一定会执行验证方法

原因在于:代理对象(d)控制着我们对目标对象(loginServlet)的引用

ideamaven银行转账 转账java_动态代理_05

代理的实现方式

静态代理

静态代理——>一个代理类 代理一个目标类(也可以表述为:一个代理对象控制着一个目标对象)

代理类可以生成代理对象,目标类可以生成目标对象

ideamaven银行转账 转账java_java_06

代理的目的:

  1. 控制访问: 通过代理对象的方式 间接 去访问目标对象,防止可以直接访问目标对象给系统代理不必要的复杂性
    使用代理,可以让用户想使用目标对象,必须先使用代理对象
  2. 功能增强: 通过代理类能够对原有业务进行增强

如何让程序知道要增强的功能是谁?

1、接口方式: 通过实现接口的方式知道哪个是要增强的功能

ideamaven银行转账 转账java_目标对象_07


ideamaven银行转账 转账java_动态代理_08

静态代理缺点:

静态代理缺点: 静态代理不可以用一个代理类来代理多个目标类,因为违反开闭原则

动态代理

真实被代理的都是由目标类所代理的目标对象

什么是动态代理

动态代理:由动态代理类生成多个代理对象来代理不同的目标类

ideamaven银行转账 转账java_java_09

动态代理的实现

如何生成不同的代理对象??——>反射

1、确定目标类 (静态代理可以直接确定代理类代理的是哪个对象,但是动态代理类不能直接确定)

—>所以使用object

代理的目标对象由用户直接决定

ideamaven银行转账 转账java_ideamaven银行转账_10


ideamaven银行转账 转账java_后端_11


2、功能的增强

  • 1.实现接口,明确要增强的方法

如何实现接口?

实现接口在动态代理当中不能使用implement去实现,要用jdk给我们提供的方法去实现接口,并生成代理对象

因为每次新增一个目标对象就要新增一个接口的话是不理智的

ideamaven银行转账 转账java_目标对象_12


getInterface返回结果是代理对象

  • 2.明确需要功能增强的方法(方法的调用)------jdk提供了一个接口InvocationHandler
    实现接口,那么接口当中所有的方法都要实现
  • invoke方法三个参数: (这三个参数不需要赋值)
  • proxy:object类型
  • method:我们通过反射获取到的目标对象当中,需要增强功能的方法
  • args:该方法的参数

    上面:通过反射调用目标类的方法
    上面这两个方法名是一样的,但是代表的意义不一样

静态代理和动态代理的区别

静态代理:

在静态代理类当中,如果新增一个目标类,那我们需要在静态代理类当中创建新增的目标类对象,这样会违反开闭原则。

(下面这样不可行)

ideamaven银行转账 转账java_动态代理_13


(下面这样可行)

ideamaven银行转账 转账java_目标对象_14


如果采用新增代理对象的同时也新增代理类——>不可行(理论可行但不现实)

——>所以让一个类生成不同的代理对象来代理不同的目标对象

动态代理:

由动态代理类生成多个代理对象来代理不同的目标类

ideamaven银行转账 转账java_后端_15


代理对象A代理目标对象A,能不能让代理对象A代理目标对象B

—> 答:不可行

—> 原因:代理对象和目标对象之间是有一对一的关联性的

体现在哪里?

—> 体现在代理对象要对目标对象的业务进行增强。代理对象一定要实现目标对象的接口

ideamaven银行转账 转账java_后端_16