(造轮子)手写Spring框架-动态代理(基于JDK的动态代理和基于CGLIB的动态代理)

178 阅读3分钟

动态代理(基于JDK的动态代理和基于CGLIB的动态代理)

代码地址:github.com/WangChao-ly…

建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!

AopProxy是获取代理对象的抽象接口,JdkDynamicAopProxy的基于JDK动态代理的具体实现。TargetSource,被代理对象的封装。MethodInterceptor,方法拦截器,是AOP Alliance的"公民",顾名思义,可以拦截方法,可在被代理执行的方法前后增加代理行为。

基于CGLIB的动态代理实现逻辑也比较简单,查看CglibAopProxy。与基于JDK的动态代理在运行期间为接口生成对象的代理对象不同,基于CGLIB的动态代理能在运行期间动态构建字节码的class文件,为类生成子类,因此被代理类不需要继承自任何接口。


前置知识:MethodMatcher methodMatcher = new AspectJExpressionPointcut("execution(* org.springframework.test.service.WorldService.explode(..))").getMethodMatcher();

根据表达式能匹配到类和方法。

基于JDK的动态代理

  1. TargetSource:被代理的目标类,该类主要对需要代理的类进行包装。
public class TargetSource {
    private final Object target;

    public TargetSource(Object object){
        this.target = object;
    }

    //表示目标对象实现的接口数组
    public Class<?>[] getTargetClass(){
        return this.target.getClass().getInterfaces();
    }

    public Object getTarget(){
        return this.target;
    }
}
  1. MethodMatcher:方法匹配接口,用来接收表达式能匹配到的全部类和方法。
public interface MethodMatcher {
    /**
     * 方法匹配
     * @param method
     * @param targetClass
     * @return
     */
    boolean matches(Method method, Class<?> targetClass);
}
  1. AdvisedSupport:该类是它用于支持和管理代理对象的相关配置和信息,还包括目标对象和匹配类信息,后面获取这些对象都是在这个类中获取。
public class AdvisedSupport {
    /**
     * 被代理对象
     */
    private TargetSource targetSource;
    /**
     * 方法拦截器是一种在方法调用前后进行额外逻辑处理的机制
     */
    private MethodInterceptor methodInterceptor;
    /**
     * 方法匹配
     */
    private MethodMatcher methodMatcher;

    public TargetSource getTargetSource(){
        return this.targetSource;
    }

    public void setTargetSource(TargetSource targetSource){
        this.targetSource = targetSource;
    }

    public MethodInterceptor getMethodInterceptor(){
        return this.methodInterceptor;
    }

    public void setMethodInterceptor(MethodInterceptor methodInterceptor){
        this.methodInterceptor = methodInterceptor;
    }

    public MethodMatcher getMethodMatcher(){
        return this.methodMatcher;
    }

    public void setMethodMatcher(MethodMatcher methodMatcher){
        this.methodMatcher = methodMatcher;
    }
}
  1. AopProxy:代理接口,提供获取代理对象的接口。
  2. JdkDynamicAopProxy:这个类实现了AopProxy, InvocationHandler能够获取代理对象,和提供代理的对象有方法被调用时,会触发invoke方法,在这里面可以对方法进行增强,其中ReflectiveMethodInvocation类是对目标类进行包装,MethodInterceptor.invoke会调用我们定义的切面方法。
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
    private final AdvisedSupport advised;
    public JdkDynamicAopProxy(AdvisedSupport advised){
        this.advised = advised;
    }

    /**
     * 被代理的对象(该对象)有方法被调用时,会触发该方法
     * @return
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //判读被代理的对象中执行的方法,是不是我们规定匹配的方法
        if(advised.getMethodMatcher().matches(method,advised.getTargetSource().getTarget().getClass())){
            //代理方法
            MethodInterceptor methodInterceptor = advised.getMethodInterceptor();
            return methodInterceptor.invoke(new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(),method,args));
        }
        //如果执行的不是代理方法,直接执行,不做增强
        return method.invoke(advised.getTargetSource().getTarget(), args);
    }

    /**
     * 返回代理对象
     * @return
     */
    @Override
    public Object getProxy() {
        //ClassLoader loader,
        //Class<?>[] interfaces,
        //InvocationHandler h 传入这个类
        return Proxy.newProxyInstance(getClass().getClassLoader(),advised.getTargetSource().getTargetClass(),this);
    }
}

基于CGLIB的动态代理

  1. CGLIB的动态代理是基于Enhancer来生成的对象,具体和上面差不多。
public class CglibAopProxy implements AopProxy{
    private final AdvisedSupport advised;
    public CglibAopProxy(AdvisedSupport advised){
        this.advised = advised;
    }

    @Override
    public Object getProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(advised.getTargetSource().getTarget().getClass());
        enhancer.setInterfaces(advised.getTargetSource().getTargetClass());
        //设置Callback
        enhancer.setCallback(new DynamicAdvisedInterceptor(advised));
        return enhancer.create();
    }

    private static class DynamicAdvisedInterceptor implements MethodInterceptor {
        private final AdvisedSupport advised;
        public DynamicAdvisedInterceptor(AdvisedSupport advised){
            this.advised = advised;
        }

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            CglibMethodInvocation methodInvocation = new CglibMethodInvocation(advised.getTargetSource().getTarget(), method, objects, methodProxy);
            if (advised.getMethodMatcher().matches(method, advised.getTargetSource().getTarget().getClass())) {
                //代理方法
                return advised.getMethodInterceptor().invoke(methodInvocation);
            }
            return methodInvocation.proceed();
        }
    }

    /**
     * 目标对象封装类
     */
    private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
        private final MethodProxy methodProxy;
        private Object target;
        private Object[] arguments;

        public CglibMethodInvocation(Object target, Method method, Object[] arguments, MethodProxy methodProxy) {
            super(target, method, arguments);
            this.methodProxy = methodProxy;
            this.target = target;
            this.arguments = arguments;
        }

        @Override
        public Object proceed() throws Throwable {
            return this.methodProxy.invoke(this.target, this.arguments);
        }
    }
}