静态代理:
真实角色和代理角色实现相同的接口,代理角色拥有真实角色的引用。代理角色去执行方法,对于某些“真正”需要真实角色自己执行的方法时,在代理角色内部就调用真实角色的方法,其他的就可以执行代理角色的方法(例如房主和中介,有带领客户看房,签合同,交钱,收房等方法,那么签合同、交钱就是“真正”需要真实角色自己执行的方法,其他的方法就可以直接交给中介去执行)
应用场景:
1)安全代理:屏蔽对真实角色的直接访问
2)延迟加载:先加载轻量级的代理对象,真正需要时再加载真实对象
动态代理:
实现方式有:JDK自带的动态代理; javaassist字节码操作库实现;CGUB;ASM
JDK自动的动态代理:
代码实现:
// 接口 public interface IAccount { IAccount deposit(double money); double getBalance(); }
// 真实角色 public class Account implements IAccount{ private double balance = 100; @Override public IAccount deposit(double money) { balance += money; return null; } @Override public double getBalance() { return balance; } }
// 处理器 public class AccountHandler implements InvocationHandler{ IAccount account; public AccountHandler(IAccount account) { this.account = account; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("deposit".equals(method.getName())) { method.invoke(account, args); return proxy; }else { return method.invoke(account, args); } } }
// 应用 public class Client02 { public static void main(String[] args) { IAccount account = new Account(); AccountHandler handler = new AccountHandler(account); IAccount proxy = (IAccount) Proxy.newProxyInstance(account.getClass().getClassLoader(), account.getClass().getInterfaces(), handler); IAccount proxy1 = proxy.deposit(100); double b = proxy.getBalance(); System.out.println(b); } }
结果:
可以看到在处理器那个代码里面,invoke()里面的两处的返回有些不同,一般的就直接一句代码:return method.invoke(account, args)
这里写这么多是为了体现 public Object invoke(Object proxy, Method method, Object[] args) 参数proxy 的作用:
取至源码(对invoke()方法的说明):
意思: 1:当一个方法在代理对象上被调用 will be(实际上是) 在 invocation handler上调用
2: method是在参数proxy 上被调用
proxy <-------> this
// 将上面代码的应用部分改成: public class Client02 { public static void main(String[] args) { IAccount account = new Account(); AccountHandler handler = new AccountHandler(account); IAccount proxy = (IAccount) Proxy.newProxyInstance(account.getClass().getClassLoader(), account.getClass().getInterfaces(), handler); proxy.deposit(100).deposit(200); double b = proxy.getBalance(); System.out.println(b); } }
结果:
静态代理需要自定义代理对象,动态代理是动态生成代理对象