1. 程式人生 > 其它 >Spring入門系列-靜態代理模式

Spring入門系列-靜態代理模式

靜態代理模式

為什麼要學習代理模式?因為這就是SpringAop的底層!
代理模式的分類:

  • 動態代理
  • 靜態代理

角色分析:

  1. 抽象角色:一般會使用介面和抽象類來解決
  2. 真實角色:被代理的角色
  3. 代理角色:代理真實角色,代理真實角色只有,我們一般會做一些附屬的操作
  4. 客戶:訪問代理物件的人

代理模式的好處:

  1. 可以使得真實的角色的操作更加純粹,不必要去關注一些公共的業務
  2. 公共也交給了代理角色,實現了業務的分工!
  3. 公共的業務擴充套件的時候方便集中管理

程式碼步驟

  1. 介面
package com.dreamcold.aop.demo;
//租房的介面,真實角色和代理角色都需要實現該介面
public interface Rent {

    public void rent();
}

  1. 真實角色
package com.dreamcold.aop.demo;
//房東
public class Host implements Rent{
    public void rent() {
        System.out.println("房東要出租房子!");
    }
}
  1. 代理角色
package com.dreamcold.aop.demo;

public class Proxy implements Rent{

    private Host host;


    public Proxy(){

    }

    public Proxy(Host host) {
        this.host = host;
    }


    public void seeHouse(){
        System.out.println("中介帶你看房!");
    }


    public void rent() {
        seeHouse();
        this.host.rent();
        fee();
        signAContract();
    }

    public void fee(){
        System.out.println("收中介費!");
    }

    public void signAContract(){
        System.out.println("簽署合同!");
    }

}

  1. 客戶端訪問代理角色
package com.dreamcold.aop.demo;

public class Main {
    public static void main(String[] args) {
        Host host=new Host();
        Proxy proxy=new Proxy(host);
        proxy.rent();
    }
}

缺點:

  1. 一個真實角色就會產生一個代理角色,程式碼量會翻倍-開發效率會降低

加深理解

  1. 首先我們定義一個userService的服務介面
package com.dreamcold.aop.demo01;


public interface UserService {

    //增
    public void insert();
    //改
    public void update();
    //刪
    public void delete();
    //查詢
    public void find();
}

  1. 定義其的實現類userServiceImpl
package com.dreamcold.aop.demo01;

public class UserServiceImpl implements UserService {
    public void insert() {
        System.out.println("增加了一個使用者!");
    }

    public void update() {
        System.out.println("刪除了一個使用者!");
    }

    public void delete() {
        System.out.println("修改了一個使用者!");
    }

    public void find() {
        System.out.println("查詢了一個使用者!");
    }
}

  1. 現在我們希望再每個改查增刪的業務邏輯中新增日誌
package com.dreamcold.aop.demo01;

public class UserServiceImpl implements UserService {
    public void insert() {
        System.out.println("日誌:增加了使用者");
        System.out.println("增加了一個使用者!");
    }

    public void update() {
        System.out.println("日誌:更新了使用者");
        System.out.println("刪除了一個使用者!");
    }

    public void delete() {
        System.out.println("日誌:刪除了使用者");
        System.out.println("修改了一個使用者!");
    }

    public void find() {
        System.out.println("日誌:查找了使用者");
        System.out.println("查詢了一個使用者!");
    }
}

目前僅僅只有四個方法,可能覺得這樣寫還好,但是當方法一旦增加到無數方法後,那麼這樣的修改的程式碼量會很多,我們希望再補改變原有程式碼量的前提下對其進行改進,我們設定一個代理角色。

package com.dreamcold.aop.demo01;

public class UserServiceProxy implements UserService {

    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

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

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

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

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

    private void log(String msg){
        System.out.println("使用了"+msg+"方法!");
    }
}

客戶端呼叫

package com.dreamcold.aop.demo01;

public class Client {
    public static void main(String[] args) {
        UserService userService=new UserServiceImpl();
        UserServiceProxy userServiceProxy=new UserServiceProxy();
        userServiceProxy.setUserService(userService);
        userServiceProxy.find();
    }
}

為什麼我們加入日誌功能不可以在原有的程式碼上加,因為改變原有的程式碼在公司中是大忌,容易改崩掉

AOP的思想

  1. 我們原本的開發流程是前端呼叫controller層、controller層呼叫service層、service層呼叫dao層
  2. 隨著業務量的增加,原來的系統出現了BUG,我希望能在原來的系統中加入日誌的功能,我需要在原有的層中橫切進去,加入service層
  3. 即橫切進去,設定代理類,在不改變原有程式碼的情況下,增加新的功能

學習自連結:狂神說