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

 

你可能感兴趣的:(Spring技术栈,aop,proxy,jdk,java)