代理
651字约2分钟
2024-08-10
代理模式
使用一个代理对象将对象包装起来,然后用该代理对象来取代该对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时调用原始对象的方法
静态代理
这里我们拿结婚举例,结婚一般是找婚庆公司帮忙办理。婚庆公司就是代理对象,结婚的新人就是被代理对象
创建结婚接口
public interface Marry {
public abstract void marry();
}
创建真实对象
public class Newcomer implements Marry {
@Override
public void marry() {
System.out.println("一对新人结婚");
}
}
创建代理对象,婚庆公司
public class MarryCompany implements Marry {
// 给 newcomer(新人) 做代理
private Newcomer newcomer;
// 带参构造,创建对象时,将真实对象传入
public MarryCompany(Newcomer newcomer) {
this.newcomer = newcomer;
}
@Override
public void marry() {
System.out.println("结婚前的准备......");
// 真实对象结婚的方法
newcomer.marry();
System.out.println("结婚后的收尾......");
}
}
测试
public static void main(String[] args) {
// 创建一对新人
Newcomer newcomer = new Newcomer();
// 创建婚庆公司,并将真实结婚对象传入
MarryCompany marryCompany = new MarryCompany(newcomer);
marryCompany.marry();
// ------结果------
// 结婚前的准备......
// 一对新人结婚
// 结婚后的收尾......
}
动态代理
和静态代理的区别在于不用不去直接创建一个代理类,而是直接通过 JDK
提供的一个 Proxy.newProxyInstance()
创建了一个 Marry
接口对象
这种没有实现类但是在运行期动态创建了一个接口对象的方式,我们称为动态代码。JDK
提供的动态创建接口对象的方式,就叫动态代理
创建结婚接口
public interface Marry {
public abstract void marry();
}
创建真实对象
public class Newcomer implements Marry {
@Override
public void marry() {
System.out.println("一对新人结婚");
}
}
测试
public static void main(String[] args) {
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
// 这里只对 marry 方法增强
if ("marry".equals(method.getName())) {
System.out.println("结婚前的准备.....");
// 调用被代理对象方法
method.invoke(new Newcomer());
System.out.println("结婚后的收尾......");
}
return null;
}
};
Marry marry = (Marry) Proxy.newProxyInstance(Newcomer.class.getClassLoader(), Newcomer.class.getInterfaces(), handler);
marry.marry();
}
在运行期动态创建一个interface
实例的方法
定义一个
InvocationHandler
实例,它负责实现接口的方法调用通过
Proxy.newProxyInstance()
创建interface
实例,它需要3
个参数- 使用的
ClassLoader
,通常就是接口类的ClassLoader
- 需要实现的接口数组,至少需要传入一个接口进去
- 用来处理接口方法调用的
InvocationHandler
实例
- 使用的
将返回的
Object
强制转型为接口