java动态代理源码原理笔记

代理

代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理

预处理例子:spring aop的before,after,arround,exception处理。


代理的静态实现逻辑

  1. 基于接口的代理

        public class MgtInstance implements MgtInterface{
            public void dosth(){...}
        }
    
        public class MgtProxy implements MgtInterface {
            private MgtInterface mgt;
            //。。。注入mgtInstance
    
            @Override
            public void dosth(){
                
                try{
                    //...before
                    mgt.dosth...
                     //...after
                }catch(){
                    //exception
                }final{
    
                }
               
            }
        }
    
  2. 基于继承的代理

         public class MgtInstance implements MgtInterface{
             public void dosth(){...}
         }
    
         public class MgtProxy extends MgtInstance implements MgtInterface {
             
             @Override
             public void dosth(){
                 
                 try{
                     //...before
                     super.dosth();
                      //...after
                 }catch(){
                     //exception
                 }final{
    
                 }
                
             }
         }
    

代理实现的两大常用组件

上述是静态实现,动态代理使用反射,可以解耦实际操作(userDao.dosth)与 其他委托处理信息(before,after,arround, exception),

  1. jdk动态代理底层源码及原理

https://blog.csdn.net/weixin_37961431/article/details/108182253

主要涉及类
invocationhandle接口;Proxy,proxyGenerator;接口;实现类
proxyGenerator生成代理类字节流,生成class;此class是继承proxy,实现接口;依赖handle实现类作为成员变量,

    // 查看jdk动态代理的源代码
        byte[] bytes= ProxyGenerator.generateProxyClass("$Proxy0",new Class[]   {UserDao.class});
        try {
            FileOutputStream fs = new FileOutputStream(new File("D:\\$Proxy0.class"));
            fs.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }

符合设计六大原则的开闭原则:对拓展开放,对修改关闭

  1. cglib动态代理底层源码及原理

    https://jpeony.blog.csdn.net/article/details/80633194
    https://zhuanlan.zhihu.com/p/92019070

    主要涉及类:MethodInterceptor接口;enchance,methodProxy,fastClass

     public static void main(String[] args) {
         // 代理类class文件存入本地磁盘方便我们反编译查看源码
         System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\code");
         // 通过CGLIB动态代理获取代理对象的过程
         Enhancer enhancer = new Enhancer();
         // 设置enhancer对象的父类
         enhancer.setSuperclass(HelloService.class);
         // 设置enhancer的回调对象
         enhancer.setCallback(new MyMethodInterceptor());
         // 创建代理对象
         HelloService proxy= (HelloService)enhancer.create();
         // 通过代理对象调用目标方法
         proxy.sayHello();
     }
    

    符合设计六大原则的里氏替换原则:对子类可以扩展父类的功能,但不能改变父类原有的功能

  2. 两者区别

    1. JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。
    2. JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。
    3. JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。

spring aop底层源码及原理

Created with Raphaël 2.2.0 开始 My Operation Yes or No? End yes
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值