首页 Java 学习 动态代理
文章
取消

Java 学习 动态代理

代理 概念

主要是对 对象 的行为额外做出一些辅助操作

代理的作用类似一个 明星的 经纪人,经纪人会为明星的一些行为进行代理

如何创建

Java 中代理的 代表类是 java.lang.reflect.Proxy

Proxy提供了一个静态方法,用以为对象产生一个代理对象返回。

1
2
3
4
5
6
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h) {

...
}

Params:

  • loader – the class loader to define the proxy class

  • interfaces – the list of interfaces for the proxy class to implement

  • h – the invocation handler to dispatch method invocations to

流程

  1. 创建一个需要代理的对象,实现相关接口,比如 Star 类 和 Skill 接口类

  2. 为对象产生一个代理对象 比如 StarAgentProxy类

  3. 走代理对象类中实现的方法。

  4. 代理将返回结果给方法的调用者

代理 举例

Skill 接口:

1
2
3
4
public interface Skill {
    void sing();
    void dance();
}

Star 类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Star implements Skill{
    private String name;

    public Star(String name) {
        this.name = name;
    }

    @Override
    public void sing() {
        System.out.println(name+" is singing...");
    }

    @Override
    public void dance() {
        System.out.println(name+" is dancing...");
    }
}
    }
}

StarAgentProxy类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class StarAgentProxy {

    // 返回一个明星代理对象 这里返回类型为要代理的行为类 即接口
    public static Skill getProxy(Star s){
        return (Skill) Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("首付款...");
                // args 方法可能需要用到的参数 虽然这里接口方法返回是 void 但有些方法可能不是 返回对象还是写成Object,方便接收
                Object obj =  method.invoke(s,args);
                System.out.println("尾款...");
                return obj;
            }
        });
    }

    public static void main(String[] args) {
        Star star = new Star("cxk");
        Skill proxy = StarAgentProxy.getProxy(star);
        proxy.dance();
        proxy.sing();
        System.out.println("finished");
    }
}

示例输出:

1
2
3
4
5
6
7
首付款...
cxk is dancing...
尾款...
首付款...
cxk is singing...
尾款...
finished

代理中的返回对象可以写为泛型 即 Skill 改为 T ; 后面的 Star 改为 T; return (Skill) 改成 (T) 即 实现了对任意接口类型的实现类对象做代理

泛型:

1
2
3
4
5
6
7
8
9
10
11
12
public static <T> T getProxy(T s){
        return (T) Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("首付款...");
                // args 方法可能需要用到的参数 虽然这里接口方法返回是 void 但有些方法可能不是 返回对象还是写成Object,方便接收
                Object obj =  method.invoke(s,args);
                System.out.println("尾款...");
                return obj;
            }
        });
    }

// 以上内容主要参考 黑马程序员

本文由作者按照 CC BY 4.0 进行授权

Java 学习 注解

Java 后端同前端交互