动态代理
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
                    
                
                
            
        
浙公网安备 33010602011771号