hooyantsing's Blog

P93 代理模式(3)-动态代理

字数统计: 426阅读时长: 1 min
2020/11/11

尚硅谷Java设计模式(图解+框架源码剖析)

动态代理

基本介绍
  1. 代理对象,不需要实现接口,但是目标对象要实现接口,否则不能用动态代理
  2. 代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象
  3. 动态代理也叫做:JDK代理,接口代理
JDK中生成代理对象的API
  1. 代理类所在包:java.lang.reflect.Proxy
  2. JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数

案例 课堂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classDiagram
class ITeacherDao{
<<interface>>
+teach() void
}
class TeacherDao{
+teach() void
}
class ProxyFactory{
+ProxyFactory()
+getProxyInstance() Object
}
class Client
ITeacherDao <|.. TeacherDao
ProxyFactory <.. Client

共同实现的接口

1
2
3
public interface ITeacherDao {
void teach();
}

被代理类

1
2
3
4
5
6
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("上课中");
}
}

动态代理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ProxyFactory {
private Object target;

public ProxyFactory(Object target) {
this.target = target;
}

public Object getProxyInstance() {
/*
1. ClassLoader loader : 指定当前目标对象使用的类加载器,获取加载器的固定方法
2. Class<?>[] interfaces : 目标对象实现的接口类型,使用泛型方法确认类型
3. InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> {
System.out.println("准备上课");
Object methodVal = method.invoke(target,args);
System.out.println("准备下课");
return methodVal;
});
}
}

调用测试:

1
2
3
4
5
6
7
8
9
10
11
12
public class Client {
public static void main(String[] args) {
// 创建目标对象
ITeacherDao teacherDao = new TeacherDao();

// 给目标对象,创建代理对象
ITeacherDao proxyInstance = (ITeacherDao) new ProxyFactory(teacherDao).getProxyInstance();
// 类名 $Proxy0 表示一个代理对象
System.out.println("proxyInstance=" + proxyInstance.getClass());
proxyInstance.teach();
}
}
CATALOG
  1. 1. 动态代理
    1. 1.1. 基本介绍
    2. 1.2. JDK中生成代理对象的API
  2. 2. 案例 课堂