设计模式之代理模式(cglib动态代理)

文章目录

 


前言

提示:代理模式一般通过实现接口或者继承父类来实现对目标对象的访问


 

一、代理模式是什么?

访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

目的:   一是保护目标对象(间接访问对象);

           二是增强目标对象(可以前置,后置或者环绕增强,处理异常等,如SpringAOP)。

二、代理模式简介

1.接口代理(如JDK动态代理)

静态代理:

 目标对象 A 实现接口 B重写方法 request();

代理类 Proxy 也同样实现 接口 B, 并且通过聚合方式将目标作为代理Proxy的成员

代理Proxy 重写方法 request(),拦截了目标A的方法request(),能够对其前置,后置等增强处理

缺点:必须有接口,jdk动态代理还使用了反射,效率没有cglib快

2.继承代理(如cglib动态代理的实现,Spring AOP)

 继承代理方式 通过对真实目标进行继承重写请求方法来处理

缺点: 被代理类不能是final修饰的

原理大概如下:

aop:

cglib动态代理 SpringAOP(源码分析):

MethodInterceptor: 方法拦截接口
public interface MethodInterceptor extends Callback {
    Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
}

CglibAopProxy.class

   public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
        }

        try {
            //真实被代理对象
            Class<?> rootClass = this.advised.getTargetClass();
            Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
           //被代理对象作为父类,代理者是他的子类
            Class<?> proxySuperClass = rootClass;
            int x;
            if (rootClass.getName().contains("$$")) {
                proxySuperClass = rootClass.getSuperclass();
                Class<?>[] additionalInterfaces = rootClass.getInterfaces();
                Class[] var5 = additionalInterfaces;
                int var6 = additionalInterfaces.length;

                for(x = 0; x < var6; ++x) {
                    Class<?> additionalInterface = var5[x];
                    this.advised.addInterface(additionalInterface);
                }
            }

            this.validateClassIfNecessary(proxySuperClass, classLoader);
            //Enhancer 动态代理 拦截方法的处理类
            Enhancer enhancer = this.createEnhancer();
            if (classLoader != null) {
                enhancer.setClassLoader(classLoader);
                if (classLoader instanceof SmartClassLoader && ((SmartClassLoader)classLoader).isClassReloadable(proxySuperClass)) {
                    enhancer.setUseCache(false);
                }
            }
            //给代理设置父类
            enhancer.setSuperclass(proxySuperClass);
            enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
            Callback[] callbacks = this.getCallbacks(rootClass);
            Class<?>[] types = new Class[callbacks.length];

            for(x = 0; x < types.length; ++x) {
                types[x] = callbacks[x].getClass();
            }

            enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);
            //返回代理子类
            return this.createProxyClassAndInstance(enhancer, callbacks);
        } catch (IllegalArgumentException | CodeGenerationException var9) {
            throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", var9);
        } catch (Throwable var10) {
            throw new AopConfigException("Unexpected AOP exception", var10);
        }
    }

总结

        接口代理必须要有接口,而继承方式则不能是final.

        写文不易,有错误的地方还望评论区指正补充! 谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值