0%

10.代理模式

10.代理模式

为什么要学习代理模式?因为这就是SpringAOP的底层!【SpringAOP和SpringMVC】

代理模式分类:

  • 静态代理

  • 动态代理

    10.1静态代理

  • 抽象角色:一般会使用接口或者抽象类类解决

  • 真实角色:被代理的角色

  • 代理角色:代理真实角色,代理真实角色后会做一些附属操作

  • 客户:访问代理对象的人

代码步骤:

  1. 接口

    1
    2
    3
    4
    5
    package com.lwj.demo01;
    //租房
    public interface Rent {
    public void rent();
    }
  2. 真实角色

    1
    2
    3
    4
    5
    6
    7
    8
    package com.lwj.demo01;
    //房东
    public class Host implements Rent {

    public void rent() {
    System.out.println("房东要出租房子");
    }
    }
  3. 代理角色

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.lwj.demo01;
    public class Proxy implements Rent{
    private Host host;

    public Proxy() {
    }
    public Proxy(Host host) {
    this.host = host;
    }
    //重写的公有方法
    public void rent() {
    fare();
    seeHouse();
    host.rent();
    }
    //看房
    public void seeHouse(){
    System.out.println("中介带你看房子");
    }
    //收中介费
    public void fare(){
    System.out.println("收中介费");
    }
    }
  1. 客户端访问代理角色
1
2
3
4
5
6
7
8
9
10
11
12
package com.lwj.demo01;

public class Client {
public static void main(String[] args) {
//房东要租房子
Host host = new Host();
//代理,中介帮房东租房子,中介其中还有一些附属操作
Proxy proxy= new Proxy(host);
//你不用面对房东,直接找中介就行了
proxy.rent();
}
}

代理模式的优点:

  • 可以是真实角色的操作更加纯粹,不用去关注太多公共业务!
  • 公共也就交给代理角色!实现了业务的分工!
  • 公共业务发生扩展的时候,方便集中管理!

代理模式缺点:

  • 一个真实角色就会产生一个代理角色;代码量会翻倍,开发效率变低

10.2加深理解静态代理

在不改动原有代码的基础上增加日志功能

(在方法调用之前输出方法名)

  1. 接口

    1
    2
    3
    4
    5
    6
    public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
    }
  2. 实现类(原有代码)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //真实的对象
    public class UserServiceImpl implements UserService {
    public void add() {
    System.out.println("增加了一个用户");
    }

    public void delete() {
    System.out.println("删除了一个用户");
    }

    public void update() {
    System.out.println("修改了一个用户");
    }

    public void query() {
    System.out.println("查询了一个用户");
    }

    //1.改动原有的业务代码,在公司中是大忌
    }
  3. 代理类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class UserServiceProxy implements UserService{
    UserServiceImpl userService;//首先把真实对象拿过来

    //推荐使用set方法,不建议使用构造方法
    public void setUserService(UserServiceImpl userService) {
    //注入真实对象
    this.userService = userService;
    }

    public void add() {
    log("add");
    userService.add();
    }

    public void delete() {
    log("delete");
    userService.delete();
    }

    public void update() {
    log("update");
    userService.update();
    }

    public void query() {
    log("query");
    userService.query();
    }
    //日志方法
    public void log(String msg){
    System.out.println("使用了"+msg+"方法");
    }
    }
  4. 客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Client {
    public static void main(String[] args) {
    UserServiceImpl userService = new UserServiceImpl();

    UserServiceProxy userServiceProxy = new UserServiceProxy();
    userServiceProxy.setUserService(userService);
    userServiceProxy.add();
    }
    }

    执行结果:

    1
    2
    3
    4
    5
    "C:\Program Files\Java\jdk1.8.0_221\bin\java.exe" 
    使用了add方法
    增加了一个用户

    Process finished with exit code 0

10.3动态代理

  • 动态代理和静态代理角色一样
  • 动态代理的类是动态生成的,不是我们写好的
  • 动态代理分为两大类:
    • 基于接口的:JDK动态代理【重点】
    • 基于类:cglib
    • Java字节码实现

需要了解两个类:Proxy(代理),InvocationHandler(调用处理程序)

动态代理的本质就是利用反射实现的。

反射没学好,等补课了反射,再来补上这个博客。。