1. 程式人生 > >Spring AOP動態代理之JDK代理

Spring AOP動態代理之JDK代理

前言

我們都知道AOP中的代理就是由AOP框架動態生成的一個物件,該物件可以作為目標物件使用。此處講解Spring中的AOP代理之JDK動態代理。

JDK代理是什麼

JDK動態代理是通過java.lang.reflect.Proxy類來實現的,我們可以呼叫Proxy了的newProxyInstance()方法來建立代理物件。對於使用業務介面的類,Spring預設會使用JDK動態代理來實現AOP.

實戰

1.建立介面UserDao類

package com.aop.jdk;

public interface UseDao {
    public void addUser();
    public void deleteUser();
}

2.建立目標類UserDaoImpl實現UserDao介面

package com.aop.jdk;
import com.ioc.UserDao;

//目標類
public class UserDaoImpl implements UseDao {
    @Override
    public void addUser() {
        System.out.println("新增使用者");
    }

    @Override
    public void deleteUser() {
        System.out.println("刪除使用者");
    }
}

3.建立切面類MyAspect

package com.aop.jdk;

//切面類:可以存在多個通知Advice(即增強的方法)
public class MyAspect {
    public void check_Permission(){
        System.out.println("模擬檢查許可權");
    }
    public void log(){
        System.out.println("模擬記錄日誌");
    }
}

4.建立代理類JdkProxy

package com.aop.jdk;

import org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer;

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


//動態代理
public class JdkProxy implements InvocationHandler{
    //宣告目標類介面
    private UseDao useDao;
    //建立代理方法
    public Object createProxy(UseDao useDao){
        this.useDao = useDao;
        //類載入器
        ClassLoader classLoader = JdkProxy.class.getClassLoader();
        //被代理物件實現的所有介面
        Class<?>[] clazz = useDao.getClass().getInterfaces();
        //使用代理類進行增強,返回的是代理後的物件
        return Proxy.newProxyInstance(classLoader,clazz,this);
    }
    /*
    * 所有動態代理類的方法呼叫,都會交由invoke()方法區處理
    * proxy 被代理後的物件
    *method將要執行的方法資訊(反射)
    * args執行方法時需要的引數
    * */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //宣告切面
        MyAspect myAspect = new MyAspect();
        //前增強
        myAspect.check_Permission();
        //在目標類上呼叫方法,並傳入引數
        Object obj = method.invoke(useDao, args);
        //後增強
        myAspect.log();
        return obj;


    }

}

5.建立測試類

package com.aop.jdk;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class TestJdk {
    public static void main(String[] args) {
        //建立代理物件
        JdkProxy jdkProxy = new JdkProxy();
        //建立目標物件
        UseDao useDao = new UserDaoImpl();
        //從代理物件中獲取增強後的目標物件
        UseDao useDao1 = (UseDao) jdkProxy.createProxy(useDao);
        useDao1.addUser();
        useDao1.deleteUser();
    }


}

執行結果 image

掃描關注下面二維碼獲得更多有用的資源! 這裡寫圖片描述