java动态代理 一、代理模式 二、静态代理 三、动态代理

一、代理模式

为其他对象提供一个代理以控制对某个对象的访问,代理类负责在被代理类执行服务前后进行预处理和后置处理,真实的服务提供者仍是被代理类。
比如一个用户类具有登陆功能,可以提供一个代理类,在不修改源代码的情况下给其加上权限认证。

二、静态代理

静态代理就是一个代理类只能为一个被代理类提供服务,以明星和经纪人举例,明星(被代理类)本人有收钱的行为,有了经纪人(代理类)就可以委托经纪人(代理类)进行收款,在此基础上经纪人可以在收款前发送卡号,收款后发送确认信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码class Singer implements Person{  //被代理类明星
@Override
public void collectMoney() {
System.out.println("明星本人收钱");
}
}
class SingerProxy implements Person{ //代理类 (可以理解为明星经纪人)
private Person person=new Singer();
@Override
public void collectMoney() {
System.out.println("Before invoke collectMoney");
person.collectMoney();
System.out.println("After invoke collectMoney");
}
}
1
2
3
4
5
java复制代码public static void main(String[] args) {
//静态代理
SingerProxy singerProxy=new SingerProxy();
singerProxy.collectMoney();
}

运行结果:Before invoke collectMoney 指在执行收钱行为之前一系列预处理操作

After invoke collectMoney指在收钱后一系列后置操作

1.png

三、动态代理 Proxy

java.lang.reflect.Proxy 中提供了Proxy类来实现动态代理。动态代理可以实现一个代理类代理多个被代理类

提供了下面这一获取代理实例的静态方法

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

参数描述:

1
2
3
makefile复制代码loader:定义代理类的类加载器
interfaces:代理类要实现的接口列表
h:指派方法调用的调用处理程序

java.lang.reflect包中提供了一个接口InvocationHandler

Object invoke(Object proxy, Method method, Object[] args)

参数描述:

proxy - 在其上调用方法的代理实例

method - 对应于在代理实例上调用的接口方法的 Method 实例。 Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。

args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
java复制代码interface Person{
void collectMoney();
}
class Singer1 implements Person{ //被代理类明星
@Override
public void collectMoney() {
System.out.println("明星1本人收钱");
}
}

class Singer2 implements Person{ //被代理类明星
@Override
public void collectMoney() {
System.out.println("明星2本人收钱");
}
}

interface Animal{
void eat();
}
class Cat implements Animal{

@Override
public void eat() {
System.out.println("猫吃饭");
}
}

//动态代理
class ProxyHandler implements InvocationHandler{
private Object object;
public ProxyHandler(Object object){
this.object=object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before invoke"+method.getName());
method.invoke(object,args);
System.out.println("After invoke"+method.getName());
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
java复制代码public static void main(String[] args) {
//动态代理
Person singer1=new Singer1();//被代理类singer1
Person singer2=new Singer2();//被代理类singer2
Animal cat=new Cat();//被代理类cat
ProxyHandler proxyHandler1 = new ProxyHandler(singer1);//创建singer1的代理类的处理程序
ProxyHandler proxyHandler2 = new ProxyHandler(singer2);//创建singer2的代理类的处理程序
ProxyHandler proxyHandler3 = new ProxyHandler(cat);//创建singer3的代理类的处理程序

Person singer1Proxy = (Person)Proxy.newProxyInstance(singer1.getClass().getClassLoader(), singer1.getClass().getInterfaces(), proxyHandler1);//创建singer1的代理类实例
Person singer2Proxy = (Person)Proxy.newProxyInstance(singer2.getClass().getClassLoader(),singer2.getClass().getInterfaces(),proxyHandler2);//创建singer2的代理类实例
Animal catProxy = (Animal)Proxy.newProxyInstance(cat.getClass().getClassLoader(), cat.getClass().getInterfaces(), proxyHandler3);//创建singer3的代理类实例

singer1Proxy.collectMoney();
singer2Proxy.collectMoney();
catProxy.eat();
}

运行结果:

1.png

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%