什么是动态代理

1.动态代理是java中一个非常重要的技术,很多javaWeb框架都用到了这个技术,就比如spring中的事务管理。

2.动态代理技术就是用来产生一个对象的代理对象的

我们查看javaAPI,发现proxy主要有四个方法,最常用的就是最下面一个

java动态路由的作用是什么 java动态是什么意思_java动态路由的作用是什么

原对象和代理对象之间的关系

代理对象应该具有和原对象相同的方法,就比如一个明星和它的经纪人的关系,明星一般不会自己过去谈生意,而是经纪人去,就好比一个公司找这个明星唱歌,那他应该先去找明星的经纪人,但是经纪人实际上是不会唱歌的,所以经纪人最后才会去找这个明星

java动态路由的作用是什么 java动态是什么意思_动态代理_02

如何生成代理对象

下面我们通过这个方法来产生指定对象的代理对象

java动态路由的作用是什么 java动态是什么意思_java动态路由的作用是什么_03


观察这个方法发现里面有三个参数,他们的作用如下

ClassLoader loader:指明生成代理对象使用哪个类装载器,白话的意思就是生成之后的代理对象你要用哪个类来装它(代理对象)

Class<?>[] interfaces:指明生成哪个对象的代理对象,看到interface可以知道能知道为什么java中规定,要想产生一个对象的代理对象,那么这个对象必须要有一个接口这句话是为什么了

InvocationHandler h:这个代理对象要做什么事情

下面我们就写具体例子来实现

首先肯定要有个接口

java动态路由的作用是什么 java动态是什么意思_java动态路由的作用是什么_04


然后是它的实现类

java动态路由的作用是什么 java动态是什么意思_动态代理_05


然后写个代理类

**
 * 明星的代理类
 * ClassName:StartProxy
 * Author:LFM
 * Date:2019/7/25 11:24
 **/
public class StartProxy {
    //先把明星传进来,这样代理类才能知道要代理谁啊
    //因为要提供一个接口,所以用接口声明这个明星对象的引用
    private Person start = new Start();

    //写一个方法返回明星的代理对象了
    public Person getProxy(){
        //调用方法
        return (Person)Proxy.newProxyInstance(Start.class.getClassLoader(),
                start.getClass().getInterfaces(),
                new InvocationHandler() {
                    //可以看出,这里我们使用了内部类
                    //因为这个InvocationHandler接口只有一个方法
                    //我们称这个样的接口叫做函数式接口,官方建议使用内部类或者lambda表达式
                    //这个方法有三个参数
                    //Object proxy:传入代理对象
                    //Method method:传入代理对象的当前方法
                    //Object[] args:把方法的参数也传进来
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        //这里可以让代理对象做一些操作(例如经纪人在这里谈生意)
                        //所以这里调用的就是代理对象的方法
                        //这个getName()是用来得到方法名的
                        if (method.getName().equals("song")){
                            System.out.println("我是该明星的经纪人,钱给到位马上安排!!");
                        }
                        //公司给够钱了,但是经纪人不会唱歌,所以现在就去找明星来唱
                        //所以这里调用的就是原对象的方法
                        return method.invoke(start,args);
                    }
                });
    }

然后写个测试类

java动态路由的作用是什么 java动态是什么意思_代理类_06


结果

java动态路由的作用是什么 java动态是什么意思_动态代理_07

最后说一点儿小问题,就是JDK1.8之后内部类调用外部类的成员变量的时候,成员变量不用手动加final关键字了,底层Java帮我们实现了,所以可以看到我这边那个传入进来的成员变量没有加final关键字

我们可以看出,在动态代理技术里,由于不管用户调用代理对象的什么方法,最后都是调用处理器的invoke方法。所以利用这个invoke()方法的参数(代理对象的方法名和参数),就可以知道用户调用的是什么方法,利用这个特性,就可以实现一些特殊需求,例如动态为某个对象添加额外的功能,就可以进行AOP操作,就像是spring中事务的管理。