1. 程式人生 > >Spring面向切面程式設計(AOP)原理一之使用JDK實現動態代理

Spring面向切面程式設計(AOP)原理一之使用JDK實現動態代理

  1. 什麼是面向切面程式設計?
    AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP(面向物件程式設計)的延續,是軟體開發中的一個熱點,也是Spring框架中的一個重要內容,是函數語言程式設計的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
    簡單的說,AOP就是在不破壞原有的類的基礎上,生成一個代理類,可以在原來的類上進行增強,實現可以隨時新增、取消新增的功能。
  2. 使用JDK中方法實現動態代理,必要條件:要有介面

建立一個介面

public interface UserDao {
   public void delete();
   public void save();
}

建立介面實現類

public class UserDaoImpl implements UserDao {

    @Override
    public void delete() {
        System.out.println("執行刪除操作");
    }

    @Override
    public void save() {
        System.out.println("執行儲存操作");
    }
}

建立代理物件

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


//使用JDK中的方法,實現動態代理,必須要有介面。。。
public class UserDaoJDKProxy {

    public UserDao createJDKProxy(UserDao userdao){
        UserDao UserDaoproxy =(UserDao) Proxy.newProxyInstance(userdao.getClass().getClassLoader(),
                userdao.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        /*//實現方法的動態增強
                        check();*/

                        //篩選某個方法進行增強
                        if("save".equals(method.getName())){
                            //實現方法的動態增強
                            check();
                            return (UserDao) method.invoke(userdao, args);
                        }

                        //返回的就是一個代理物件,代理物件執行方法的時候,就會進來回調
                        UserDao o = (UserDao) method.invoke(userdao, args);

                        return o;
                    }
                });
        return UserDaoproxy;
    }

    //定義需要被增強(代理)的方法
    public void check(){
        System.out.println("儲存之前進行校驗");
    }
}

編寫測試方法

import org.junit.Test;

public class UserDaoTest {

    UserDao userdao = new UserDaoImpl();
    UserDaoJDKProxy userDaoJDKProxy = new UserDaoJDKProxy();

    @Test
    public void test(){
        //建立一個代理物件
        UserDao jdkProxy = userDaoJDKProxy.createJDKProxy(userdao);
        //代理物件呼叫方法,到建立的地方回撥
        jdkProxy.delete();
        jdkProxy.save();
    }


}

執行結果

執行刪除操作
儲存之前進行校驗
執行儲存操作

Process finished with exit code 0

可以看到已經實現了對save()方法實現了增強,這就是動態代理的過程。
使用JDK建立代理物件,就是利用其中的反射機制,在原物件呼叫方法的時候,會到代理物件中進行方法的回撥。
但是必須要有介面的存在,就是面向介面程式設計。