动态代理

JDK动态代理

例子:

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

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/2/16 17:25
 */


interface Calculator {
    void add();
    void sub();

}

class CalculatorImp implements Calculator {
    @Override
    public void add() {
        System.out.println("加法");
    }

    @Override
    public void sub() {
        System.out.println("减法");
    }
}

//计算代理类需要实现InvocationHandler接口,并且含有被代理类的对象
class CalculatorProxy implements InvocationHandler {

    private Object object;

    public CalculatorProxy(Object object){

        this.object = object;

    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        //method 与代理对象调用的方法对应
        System.out.println("计算前");
        method.invoke(object, objects);
        System.out.println("计算后");
        return null;
    }
}

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

        //定义被代理对象
        Calculator calculator = new CalculatorImp();

        final Calculator proxy = (Calculator) Proxy.newProxyInstance(
                calculator.getClass().getClassLoader(),
                calculator.getClass().getInterfaces(),
                new CalculatorProxy(calculator));

        proxy.sub();
        System.out.println("-----------");
        proxy.add();
    }
}

结果

计算前
减法
计算后
-----------
计算前
加法
计算后

总结:JDK动态代理最致命的缺点就是只能代理实现了接口的类,使用CGLIB动态代理可以解决这个问题

CGLIB动态代理

/**
 * 被代理类(无需实现接口)
 * @author Pickle
 * @version V1.0
 * @date 2024/2/16 20:17
 */
public class Calculator {

    public void sub() {

        System.out.println("sub");

    }

    public void add(){
        System.out.println("add");
    }
}

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 自定义方法拦截器
 * @author Pickle
 * @version V1.0
 * @date 2024/2/16 20:18
 */
public class MyMethodInterceptor implements MethodInterceptor{
    /**
     * @param o             被代理的对象
     * @param method        被拦截的方法
     * @param objects       方法入参
     * @param methodProxy   用于调用原始方法
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("before method " + method.getName());

        methodProxy.invokeSuper(o, objects);

        System.out.println("after method " + method.getName());

        return objects;
    }
}

import net.sf.cglib.proxy.Enhancer;

/**
 * 代理类工厂
 * @author Pickle
 * @version V1.0
 * @date 2024/2/16 20:22
 */
public class CglibProxyFactory {

    /**
     * @param clazz     被增强类的class对象
     */
    public static Object getProperty(Class<?> clazz) {
        //创建动态代理增强类
        final Enhancer enhancer = new Enhancer();
        //设置类加载器
        enhancer.setClassLoader(clazz.getClassLoader());
        //设置被代理类
        enhancer.setSuperclass(clazz);
        //设置方法拦截器
        enhancer.setCallback(new MyMethodInterceptor());

        return enhancer.create();
    }

}

执行


public class execute {
    public static void main(String[] args) {
        final Calculator aliSmsServiceProxy = (Calculator) CglibProxyFactory.getProperty(Calculator.class);

        aliSmsServiceProxy.sub();

        System.out.println("----------------");

        aliSmsServiceProxy.add();
    }
}

结果

before method sub
sub
after method sub
----------------
before method add
add
after method add
posted @ 2024-02-16 20:40  破忒头头  阅读(17)  评论(0)    收藏  举报