1. 程式人生 > >Spring 學習筆記(六)AOP 之思想概念和作用、JDK代理與Cglib子類代理

Spring 學習筆記(六)AOP 之思想概念和作用、JDK代理與Cglib子類代理

  • 概念

AOP為Aspect Oriented Programming的縮寫,意味:面向切面程式設計。 與IOC一樣,是一種思想。

  • 作用

對業務邏輯進行分離,降低耦合度,提高程式的重用性,提高開發效率。

  • JDK動態代理(介面代理)

弱點:JDK動態代理是基於介面的, 必須有介面。

模擬:

1. 新建介面類

package org.spring.exampleAOP;

public interface People {

    void Shoot();
}

2. 新建實現類

package org.spring.exampleAOP;

public class Sadamu implements People {
    public Sadamu() {
    }

    @Override
    public void Shoot() {
        System.out.println("薩達姆開槍了");
    }
}

3. 新建代理類

package org.spring.exampleAOP;

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

public class JdkProxyUtils {
    public static Object getProxy(final Object obj) {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //代理要做的事
                        System.out.println("記錄日誌 Befor:" + obj.toString() + "  Method:  " + method.getName());
                        method.invoke(obj, args); //執行原物件方法
                        System.out.println("記錄日誌 After:" + obj.toString() + "  Method:  " + method.getName());
                        return proxy;
                    }
                });
    }
}

4. 測試

package org.spring.exampleAOP;

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

        //jdk的動態代理是基於介面
        People people = new Sadamu();
        People ppeople = (People) JdkProxyUtils.getProxy(people); //傳入值必須是介面
        ppeople.Shoot(); 

    }
}

測試結果:

記錄日誌 Befor:
[email protected]
Method: Shoot 薩達姆開槍了 記錄日誌 After:[email protected] Method: Shoot Process finished with exit code 0
  • Cglib代理(子類代理)    個人感覺是比JDK介面代理方便

1. 需要的jar包 asm.jar和cglib-2.1.3.jar

2. 新建子類代理類

package org.spring.exampleAOP;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.InvocationHandler;

import java.lang.reflect.Method;

public class CglibProxyUtils {
    public static Object getProxy(Object obj){
       return Enhancer.create(obj.getClass(), new InvocationHandler() {
           @Override
           public Object invoke(Object o, Method method, Object[] args) throws Throwable {
               System.out.println("記錄日誌 Befor:" + obj.toString() + "  Method:  " + method.getName());
               method.invoke(obj, args);
               System.out.println("記錄日誌 After:" + obj.toString() + "  Method:  " + method.getName());

               return obj;
           }
       });
    }
}

3. 測試

package org.spring.exampleAOP;

public class Test {
    public static void main(String[] args) {  
        //Cglib子類代理
        Kazhafei kazhafei = new Kazhafei();
        People pkazhafei = (People) CglibProxyUtils.getProxy(kazhafei); //傳入的物件有沒有介面都無所謂
        pkazhafei.Shoot();
    }
}