代理模式

类图

代码

IUserDao 相当于 Subject

1
2
3
interface IUserDao {
void save();
}

UserDaoImpl 相当于 RealSubject

1
2
3
4
5
class UserDaoImpl implements IUserDao{
public void save() {
System.out.println("保存用户数据");
}
}

UserDaoProxy 相当于 Proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class UserDaoProxy implements IUserDao{

private IUserDao userDao;

public UserDaoProxy(IUserDao userDao) {
this.userDao = userDao;
}

@Override
public void save() {
System.out.println("开启事务");
this.userDao.save();
System.out.println("结束事务");
}
}

JDK动态代理

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
class ProxyFactory{

//维护一个目标对象
private Object target;
public ProxyFactory(Object target){
this.target=target;
}

//给目标对象生成代理对象
public Object getProxyInstance(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始事务2");
//执行目标对象方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务2");
return returnValue;
}
}
);
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Main {
public static void main(String args[]){

IUserDao userDao = new UserDaoImpl();

IUserDao userProxy = new UserDaoProxy(userDao);

userProxy.save();

// 目标对象
IUserDao target = new UserDaoImpl();
System.out.println(target.getClass());

// 给目标对象,创建代理对象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
System.out.println(proxy.getClass());
// 执行方法【代理对象】
proxy.save();

}
}

运行结果

1
2
3
4
5
6
7
8
开启事务
保存用户数据
结束事务
class proxy.UserDaoImpl
class proxy.$Proxy0
开始事务2
保存用户数据
提交事务2

总结

概述

文中描述了2种代理方式的实现

  • 标准代理模式的实现
  • JDK动态代理实现(实现了接口的类生成代理)

GBLIB动态代理(文中没写,是面向实现类的代理)

优点

目标类可以更加关注业务本身

缺点