探祕Spring AOP (六) Spring AOP 實現原理 1

探祕Spring AOP

1、織入的時機原理概述

一、編譯期(AspectJ)java

二、類加載時(AspectJ 5+)ide

三、運行時(Spring AOP)this

運行時織入是怎麼實現的?代理

一、從靜態代理到動態代理code

二、動態代理 分爲 基於接口代理實現和基於繼承代理實現對象

二 、代理模式

客戶端經過代理對象漸漸與目標對象打交道,反之,目標對象委託代理對象與客戶端進行交流。所以代理對象能夠在目標對象方法先後,作出額外的操做,這就是代理AOP實現的原理。繼承

輸入圖片說明

代理模式類圖接口

輸入圖片說明

三 、代碼演示

一、靜態代理

  • (1)目標對象:
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println(" execute real subject request");
    }
}
  • (2)代理對象:
public class Proxy implements Subject {

    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void request() {
        System.out.println(" before 織入邏輯");
        try {
            realSubject.request();
        } catch (Exception e) {
            System.out.println("ex:"+e.getMessage());
            e.printStackTrace();
        } finally {
            System.out.println(" after 織入邏輯");
        }
    }
}
  • (3)客戶端調用接口
public interface Subject {
    public void request();
}
  • (4)客戶端調用
public class Client {
    public static void main(String[] args) {
        Subject subject = new Proxy(new RealSubject());
        subject.request();
    }
}

二、動態代理

  • (1) 動態代理
import cn.evchar.proxy.aop.RealSubject;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class JdkProxySubject implements InvocationHandler {

    private RealSubject realSubject;

    public JdkProxySubject(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object res = null;

        System.out.println("before");
        try {
            res = method.invoke(realSubject,args);
        } catch (Exception e) {
            System.out.println("ex: "+e);
            throw e;
        } finally {
            System.out.println("after");
        }
        return res;
    }
}
  • (2)客戶端調用
import cn.evchar.proxy.aop.RealSubject;
import cn.evchar.proxy.aop.Subject;

import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args) {

        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

        Subject subject = (Subject) Proxy.newProxyInstance(Client.class.getClassLoader(),
                new Class[]{Subject.class},new JdkProxySubject(new RealSubject()));

        subject.request();
        subject.hello();
    }
}
相關文章
相關標籤/搜索