• MyBatis源码解析【4】反射和动态代理


    通过之前的介绍,我们了解了几个组件的生命周期。

    它也是我们重要装备之一。

    今天我们需要搞一件更加强的装备,叫做反射和动态代理。

    如果没有这件装备的话,显然后面的源码boss是打不动的。

    顺便说一下,下面可能会提到一些名词简写,都在之前出现过,所以如果看不明白可以看一下之前的咯。

    废话少说,╭(′▽`)╯

    什么是代理

    首先我们要明白代理是什么样一个概念。

    不要想这个概念有多复杂,其实很简单的。代理从中文角度很好理解嘛。它是一个动词吧,举个实际的例子,你代理我,帮我抄作业。

    我--->你--->作业

    你代理我,相当于我让你做,或者你帮我做。

    最终抄作业这个事情呢是由你来完成的。嘻嘻。

    注意这个例子的两个关键:

    1、我没有直接操作真实的最终的对象。(我没有抄作业)

    2、你可以提供额外的服务,比如告诉我作业抄好了,或者明天有什么作业。

    那么认真的讲:

    通过代理模式,访问者没有办法操作真实的对象,只能通过代理对象去操作真实的对象。代理对象可以提供额外的服务,比操作真实对象更多的服务。

    什么是反射

    是不是很多人当提到这个概念有下面几个感觉:1、反射学过没用过。2、反射很难,但是没啥用。3、反射很危险,没事情不要乱用。

    如果你有这么几个概念的话,证明你已经对反射有一些学习和感觉了(滑稽脸)。

    如果没有的话,我建议呢,还是去好好找个大神的博客或者视频学习一下反射。因为不简单,听我一两句可能不一定明白。

    那我们这里用到反射,需要知道这几个点。

    1、在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。

    2、对于任意一个对象,都能够调用它的任意方法和属性;生成动态代理。

    3、通过一些特殊的方法得到对象,calss.forname等

    知道这些就可以了。

    如果你愿意呢,可以看一下我以前写的关于反射的几个小例子,希望能帮到你:http://www.cnblogs.com/linkstar/p/5744444.html

    什么是动态代理

    动态代理其实上面在说代理的时候以及提到了。其实就是动态的代理嘛。

    动态代理这里介绍两种:一种使用JDK的反射机制提供的代理,另一种是CGLIB代理。

    我们一种种来讲。

    JDK的动态代理。

    如何实现呢?很简单,完成两个类就可以了。

    1、服务类,也就是真正提供服务的人。

    2、代理类,代理做事情的人。

    对于JDK的动态代理的服务类来说需要额外一个接口开放给代理类哦。

    下面是代码

    接口

    public interface DemoService {
        public void demo();
    }

    实现类

    public class DemoServiceImpl implements DemoService {
        public void demo() {
            System.out.println("Test------------");
        }
    }

    代理类

    public class DemoServiceProxy implements InvocationHandler {
    
        private Object target;
    
        public Object bind(Object target){
            this.target = target;
            //利用反射将这个类DemoServiceProxy作为传入的目标类的代理类
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
    
        //代理方法
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("method : " + method.getName());
            return method.invoke(target, args);
        }
    }

    测试类

    public class DemoServiceTest {
        public static void main(String[] args) {
            DemoServiceProxy demoServiceHanler = new DemoServiceProxy();
            DemoService proxy = (DemoService) demoServiceHanler.bind(new DemoServiceImpl());
            proxy.demo();
        }
    }

    最后打印结果

    method : demo
    Test------------

    这里的这几个类的作用和功能要好好理解哦,因为后面读源码的时候需要用到。

    然后是CGLIB代理

    相对来说就没有那么复杂了,只需要一个类就可以了,不需要接口。

    public class DemoServiceCglib implements MethodInterceptor {
    
        private Object target;
    
        public Object getInstance(Object target){
            this.target = target;
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(target.getClass());
            enhancer.setCallback(this);
            return enhancer.create();
        }
    
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("method : " + method.getName());
            return proxy.invokeSuper(obj, args);
        }
    }

    测试类修改

    public class DemoServiceTest {
        public static void main(String[] args) {
            /*DemoServiceProxy demoServiceHanler = new DemoServiceProxy();
            DemoService proxy = (DemoService) demoServiceHanler.bind(new DemoServiceImpl());
            proxy.demo();*/
            DemoServiceCglib demoServiceCglib = new DemoServiceCglib();
            DemoService proxy = (DemoService) demoServiceCglib.getInstance(new DemoServiceImpl());
            proxy.demo();
        }
    }

    测试结果相同。

    这里就不深究两种动态代理的各种参数啊,方法啊。

    我们需要知道的是,在被动态代理之后,当我们调用原来的方法时候一定调用一个叫做invoke的方法。

    也就是在调用的前后我们能做很多事情了。

    上述在mybatis的源码中会出现,很重要,望理解。

    至此,装备都有了,之后就要开始进入难点了。

  • 相关阅读:
    multiselect2side双向选择列表插件改进版
    通用权限管理平台--实现站点地图
    通用权限管理平台--系统日志
    通用权限案例平台--登录认证
    通用权限管理平台--代码结构
    通用权限管理平台--功能划分
    通用权限管理平台--架构选型
    tests
    Python 2.7_多进程获取简书专题数据(一)
    python2.7 爬取简书30日热门专题文章之简单分析_20170207
  • 原文地址:https://www.cnblogs.com/linkstar/p/7118784.html
Copyright © 2020-2023  润新知