代理模式

为什么要学习代理模式?因为这是SpringAOP的底层!

代理模式的分类:

  • 静态代理
  • 动态代理

一、静态代理

角色分析:

  • 抽象角色:一般会使用接口和抽象类来解决。
  • 真实角色:被代理的角色。
  • 代理角色:代理真实角色,代理真实角色后,我们会做一些附属的操作。
  • 客户:访问代理对象的人!

代码步骤:

1.1 接口

1
2
3
public interface Rent {
public void rent();
}

1.2 真实角色

1
2
3
4
5
6
7
//房东
public class Host implements Rent{
@Override
public void rent() {
System.out.println("房东要租房子");
}
}

1.3 代理角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//中介
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
@Override
public void rent() {
host.rent();
seeHouse();
fare();
}
private void seeHouse(){
System.out.println("中介带你看房");
}
private void fare(){
System.out.println("收中介费");
}
}

1.4 客户端访问代理角色

1
2
3
4
5
6
7
8
9
10
//客户
public class Client {
public static void main(String[] args) {
//房东要出租房子!
Host host = new Host();
//代理,中介帮房东租房子,但是代理一般会有附属操作!
Proxy proxy = new Proxy(host);
//客户不用面对房东,直接找中介租房即可!
proxy.rent();
}

代理模式的好处:

  • 可以使真实角色的操作更加纯粹
  • 公共业务就交给了代理角色!实现了业务的分工!
  • 公共业务发生扩展的时候,方便集中管理!

缺点:

  • 一个真实角色就会产生一个代理角色;代码量会翻倍。

二、代理模式Demo2

2.1 接口

1
2
3
4
5
6
public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}

2.2 真实角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加用户");
}

@Override
public void delete() {
System.out.println("删除用户");
}

@Override
public void update() {
System.out.println("修改用户");
}

@Override
public void query() {
System.out.println("查询用户");
}
}

2.3 代理角色

在不改动真实角色代码的情况下,对真实的功能进行扩展。

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
public class UserServiceProxy implements UserService{
UserService userService;

public UserServiceProxy(UserService userService) {
this.userService = userService;
}

@Override
public void add() {
log("add");
userService.add();
}

@Override
public void delete() {
log("delete");
userService.delete();
}

@Override
public void update() {
log("update");
userService.update();
}

@Override
public void query() {
log("query");
userService.query();
}
public void log(String msg){
System.out.println("[Debug] 使用"+msg+"方法");
}
}

2.4 客户端访问代理

1
2
3
4
5
6
7
public class MyTest {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
UserServiceProxy userServiceProxy = new UserServiceProxy(userService);
userServiceProxy.add();
}
}

三、动态代理

  • 动态代理和静态代理角色一样。
  • 动态代理的代理类是动态生成的,不是我们直接写好的。
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理。
    • 基于接口 — JDK动态代理
    • 基于类:cglib
    • java字节码实现:javasist

需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序

  • Proxy:提供创建动态代理类和实例的静态方法。
  • InvocationHandler:调用处理程序并返回结果。

3.1 技术原型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ProxyInvocationHandler implements InvocationHandler {

//被代理的接口
private Object target;

//生成得到代理类
public void setTarget(Object target) {
this.target = target;
}
//处理代理实例,并返回结果。
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(target, args);
return result;
}
}
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
//真实角色
Host host =new Host();
//代理角色,不存在
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//设置代理的对象
pih.setTarget(host);
//动态生成代理类
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
}

动态代理的好处:

  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务。
  • 一个动态代理类可以代理多个类,只要是实现同一个接口即可。

3.2 实例

3.2.1 接口

1
2
3
4
5
6
public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}

3.2.2 接口实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("增加用户");
}

@Override
public void delete() {
System.out.println("删除用户");
}

@Override
public void update() {
System.out.println("修改用户");
}

@Override
public void query() {
System.out.println("查询用户");
}
}

3.2.3 动态代理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ProxyInvocationHandler implements InvocationHandler {
//真实角色
UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
//生成得到动态代理类
public UserService getProxy(){
UserService proxy = (UserService) Proxy.newProxyInstance(this.getClass().getClassLoader(), userService.getClass().getInterfaces(), this);
return proxy;
}

//生成代理实例并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result = method.invoke(userService, args);
return result;
}
public void log(String msg){
System.out.println("[Debug] 使用"+msg+"方法");
}
}

测试

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
//真实角色
UserServiceImpl userService = new UserServiceImpl();
ProxyInvocationHandler pih = new ProxyInvocationHandler();
//设置要代理的对象
pih.setUserService(userService);
//生成动态代理类
UserService proxy = pih.getProxy();
proxy.add();
}
-------------本文结束感谢您的阅读-------------