Spring AOP動態代理之jdk和cglib

Spring的兩大特性就是IOC和AOP(Aspect Orient Programming),AOP一般稱爲面向切面編程,主要用於事務、日誌等方面。AOP代理分爲靜態代理和動態代理,靜態代理一般是AspectJ AOP(編譯時),動態代理則爲Spring AOP(運行時)中的cglib和jdk兩種。

jdk動態代理

jdk動態代理的核心是InvocationHandler接口和Proxy類,使用jdk動態代理的前提是被代理的類必須實現一個接口。

定義一個接口

package proxy;

/**
 * jdk代理演示接口類
 * @author : vi3nty
 * @date : 16:20 2020/4/20
 */
public interface Person {
    String sayHello(String name);
}

實現類

package proxy;

/**
 * jdk動態代理實現類
 * @author : vi3nty
 * @date : 16:20 2020/4/20
 */
public class Chinese implements Person{
    @Override
    public String sayHello(String name) {
        return name+" hello";
    }
}

切面類

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

/**
 * 定義切面
 * @author : vi3nty
 * @date : 16:22 2020/4/20
 */
public class MyInvocationHandler implements InvocationHandler {
    private Object object;

    public MyInvocationHandler(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object invoke=method.invoke(object,args);
        System.out.println("after");
        return invoke;
    }
}

測試類

package proxy;

import java.lang.reflect.Proxy;

/**
 * @author : vi3nty
 * @date : 16:42 2020/4/20
 */
public class ProxyJDKTest {
    public static void main(String[] args) {
        Chinese chinese=new Chinese();
        MyInvocationHandler handler=new MyInvocationHandler(chinese);
        Person personInstance= (Person) Proxy.newProxyInstance(
                chinese.getClass().getClassLoader(),
                chinese.getClass().getInterfaces(),
                handler);
        personInstance.sayHello("jdk");
    }
}

輸出

before
jdkhello
after

Process finished with exit code 0

cglib動態代理

如果沒有實現接口的話那就需要用cglib動態代理,代理類需實現MethodInterceptor接口。

代碼實現

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * cglib測試
 * @author : vi3nty
 * @date : 16:56 2020/4/20
 */
public class MyCglib {
    public static void main(String[] args) {
        CglibProxy proxy=new CglibProxy();
        Dog dog= (Dog) proxy.getInstance(new Dog());
        dog.eat();
    }
}

class Dog{
    public void eat(){
        System.out.println("dog is eating");
    }
}

class CglibProxy implements MethodInterceptor{

    private Object target; // 代理對象
    public Object getInstance(Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        // 設置父類爲實例類
        enhancer.setSuperclass(this.target.getClass());
        // 回調方法
        enhancer.setCallback(this);
        // 創建代理對象
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("調用前");
        Object result = methodProxy.invokeSuper(o, objects); // 執行方法調用
        System.out.println("調用後");
        return result;
    }
}

輸出結果

調用前
dog is eating
調用後

Process finished with exit code 0

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章