代理 概念
主要是对 对象 的行为额外做出一些辅助操作
代理的作用类似一个 明星的 经纪人,经纪人会为明星的一些行为进行代理
如何创建
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
流程
-
创建一个需要代理的对象,实现相关接口,比如 Star 类 和 Skill 接口类
-
为对象产生一个代理对象 比如 StarAgentProxy类
-
走代理对象类中实现的方法。
-
代理将返回结果给方法的调用者
代理 举例
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;
}
});
}
// 以上内容主要参考 黑马程序员