1. 程式人生 > 實用技巧 >SpringMVC 之處理請求

SpringMVC 之處理請求

代理模式是比較重要的設計模式之一,在面向物件的系統中,有些物件由於某些原因(比如建立物件的開銷很大,或者某些操作需要安全校驗機制,或者其他的額外控制),典型應用就是AOP。

主要分為靜態代理和動態代理,靜態代理就是通過java程式碼寫死代理類,動態代理就是動態的生成代理類,主要分為jdk動態代理和cglib動態代理,區別是jdk動態代理需要被代理的物件必須有父類,執行時動態的生成父類的子類,也就是代理類和被代理類是同一個父類,跟靜態代理差不多,cglib動態代理則沒有這個限制,執行的時候動態生成被代理類的子類。

1、靜態代理

①定義父類

public interface Image {
    
void display(); }

②被代理類

public class RealImage implements Image {

    private String fileName;

    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk(fileName);
    }

    @Override
    public void display() {
        System.out.println("Display: " + fileName);
    }

    
private void loadFromDisk(String fileName) { System.out.println("Loading: " + fileName); } }

③代理類

public class ProxyImage implements Image {

    private RealImage realImage;
    private String fileName;

    public ProxyImage(String fileName) {
        this.fileName = fileName;
    }

    @Override
    
public void display() { if (Objects.isNull(realImage)) { realImage = new RealImage(fileName); } realImage.display(); } }

④測試

public class _Test {
    public static void main(String[] args) {
        Image image = new ProxyImage("test.jpg");
        image.display();
    }
}

代理類本身持有被代理類的物件,從而實現代理

2、jdk動態代理

①定義父類

public interface Subject {
    Integer sellBooks();

    String speak();
}

②被代理類

public class RealSubject implements Subject {
    @Override
    public Integer sellBooks() {
        System.out.println("賣書");
        return 1;
    }

    @Override
    public String speak() {
        System.out.println("說話");
        return "張三";
    }
}

③代理類書寫(需要實現InvocationHandler介面)

public class MyInvocationHandler implements InvocationHandler {


    private Subject realSubject;

    public MyInvocationHandler(Subject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("呼叫代理類");
        if ("sellBooks".equals(method.getName())) {
            int invoke = (int) method.invoke(realSubject, args);
            System.out.println("呼叫賣書方法");
            return invoke;
        } else {
            String invoke = (String) method.invoke(realSubject, args);
            System.out.println("呼叫說話方法");
            return invoke;
        }
    }
}

④測試

public class _Test {
    public static void main(String[] args) {
        Subject realSubject = new RealSubject();
        MyInvocationHandler invocationHandler = new MyInvocationHandler(realSubject);
        Subject proxyClass = (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Subject.class}, invocationHandler);
        proxyClass.sellBooks();
        proxyClass.speak();

    }
}

動態的生成代理物件(繼承自Proxy,實現Subject介面)