1. 什么是动态代理?
动态代理在实现阶段不用关心代理谁,而是在运行阶段才指定代理哪一个对象。常见的有Spring中的AOP就用到了动态代理。而动态代理有两部分,JDK动态代理和CGlib动态代理。本次对jdk动态代理进行整理
2. 动态代理
2.1 代理举例
还是曾经的例子,我们个人打游戏太累,找个代练给我们上分,这就是代理。
结构如图:
2.2 创建接口IGamePlayer
public interface IGamePlayer {
// 登录游戏
void login(String user, String password);
// 打怪
void killBoss();
}
2.3 创建游戏玩家GamePlayer
public class GamePlayer implements IGamePlayer {
private String name = "";
private IGamePlayer proxy = null;
public GamePlayer(String _name) {
this.name = _name;
}
@Override
public void login(String user, String password) {
System.out.println("登录名为" + user + "的用户" + this.name + "登录成功");
}
@Override
public void killBoss() {
System.out.println(this.name + "打boss");
}
}
2.4 创建动态代理类GamePlayIH
public class GamePlayIH implements InvocationHandler {
// 被代理者
Class cls = null;
// 被代理实例
Object obj = null;
public GamePlayIH(Object _obj) {
this.obj = _obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object reuslt = method.invoke(this.obj, args);
return reuslt;
}
}
2.5 创建测试场景类Client
public class Client {
public static void main(String[] args) {
// 1直接访问真实角色
IGamePlayer player = new GamePlayer("张三");
InvocationHandler handler = new GamePlayIH(player);
ClassLoader cl = player.getClass().getClassLoader();
IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl, player.getClass().getInterfaces(), handler);
proxy.login("zhangsan", "123");
proxy.killBoss();
}
}
2.6输出:
3. 代理可以对方法进行增强
当我们账户被代理登录后代练,我们应该收到登录信息,于是我们修改代理类
public class GamePlayIH implements InvocationHandler {
// 被代理者
Class cls = null;
// 被代理实例
Object obj = null;
public GamePlayIH(Object _obj) {
this.obj = _obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object reuslt = method.invoke(this.obj, args);
// 增强点
if (method.getName().equals("login")) {
System.out.println("有人在用我账号");
}
return reuslt;
}
}
输出
4. 暂时先做到这里,继续学习深入再整理