代理模式:
不改变原有对象的情况下,增强对象或者类的方法
两种实现方法:
1:如果被代理的类继承或实现了某个类,代理类同样的继承或者实现该类
public interface IAccount {
void killMonster();
}
class MyAccount implements IAccount{
@Override
public void killMonster() {
System.out.println("kill a monster...");
}
}
class ProxyAccount implements IAccount{
private MyAccount myAccount;
public ProxyAccount(MyAccount myAccount){
this.myAccount = myAccount;
}
@Override
public void killMonster() {
System.out.println("start proxy");
myAccount.killMonster();
System.out.println("proxy over");
}
}
调用:
public static void main(String[] args) {
IAccount proxy = new ProxyAccount(new MyAccount());
killMonster(proxy);
}
private static void killMonster(IAccount account) {
account.killMonster();
}
2:被代理类没有父类,根据里氏替换法则,代理类可以实现被代理类
public class MyAccount1 {
public void killMonster(){
System.out.println("kill monster");
}
}
class ProxyAccount1 extends MyAccount{
public void killMonster(){
System.out.println("proxy start");
super.killMonster();
System.out.println("proxy end");
}
}
静态代理的问题:
硬编码,代理类要实现父类的所有要实现的方法,每增强一个方法就要新增一个代理类。
使用动态代理解决,在运行时动态创建代理的类。动态代理依赖反射
如何实现动态代理?
从使用角度出发
有一个代理类,传入需要被代理的对象,根据这个对象创建代理对象
public class DynamicProxy {
// 传入被代理对象
public static Object createProxy(Object object){
ClassLoader classLoader = object.getClass().getClassLoader();
Class<?>[] interfaces = object.getClass().getInterfaces();
// 最后会调用Proxy.newProxyInstance()返回对象,剩下的就是补充参数
Object proxyInstance = Proxy.newProxyInstance(classLoader, interfaces, (proxy, method, args) -> {
// 这儿增强方法,最后返回的invoke调用哪个方法就增强了哪个方法
System.out.println("proxy start");
Object invoke = method.invoke(object, args);
System.out.println("proxy end");
return invoke;
});
return proxyInstance;
}
//使用
public static void main(String[] args) {
IAccount account = new MyAccount();
IAccount proxy = (IAccount) DynamicProxy.createProxy(account);
proxy.killMonster();
}
}