设计模式代理模式
静态代理
动态代理:
(1) 基于接口实现的动态代理
(2) 基于子类实现的动态代理
例:
创建线程的方式之一实现Runnable接口,使用了静态代理模式,而spring框架的AOP的实现基于动态代理模式。
结婚: 结婚前 代理公司布置现场, 结婚 , 结婚后 代理公司收拾
创建一个真实的对象, 创建一个代理对象,通过代理对象去执行真实对象的方法,实现一个增强
- 静态代理模式:
1.要求代理对象和真实对象实现同一个接口
2.一个真实角色就会产生一个代理角色,导致代码量翻倍
3.静态代理模式通过代理 对象可以做很多真实对象做不了的事情,实现对真实对象的一个增强,同时真实对象可以专注的去做一件事情 - 静态代理模式在jdk源码中的应用:
实现Runnable接口创建线程的方式用到了静态代理模式; - 步骤:
1.创建一个Runnable接口的实现类
2.创建一个Thread类,并将Runnable接口的实现类作为参数传递进去
3.调用Thread类对象的start方法开启多线程
Runnable接口的实现类对象是真实对象,Thread类对象是代理对象,静态代理模式要求代理对象和真实对象继承 同一个接口,Runnable接口的实现类对象和Thread类对象都继承了 Runnable接口。
动态代理: - 基于接口的动态代理:
使用JDK官方提供的一个Proxy类来动态的创建代理对象,创建方法使用Proxy类(用来生成动态代理实例的)中的newProxyInstance方法(传递三个参数,「1」ClassLoader类加载器,用于加载代理对象字节码的,和被代理对象使用相同的类加载器;「2」class[]字节码数组,用于让代理对象和被代理对象有相同方法;「3」invocationHandler(调用处理程序并返回结果),用于提供增强的代码,也就是让我们写如何代理;),基于接口的动态代理弊端就是要求被代理类最少实现一个接口,如果没有则不能使用 - 基于子类:
需要依赖第三方cglib(代码生成库,被用于AOP框架中,用以提供方法拦截操作)库,如果是maven项目则导入cglib相关的依赖即可,基于子类的动态代理要求被代理类不能是最终类。 - 好处:
不修改原有的代码基础上对方法进行增强
解决了静态代理一个真实对象必须有一个代理对象,导致类数量大大增加的缺点,一个动态代理类可以多个类,只要实现的是同一个接口即可
动态代理模式底层使用的就是java的反射。
public class Client {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//代理角色:现在没有
ProxyInvocationHandler p = new ProxyInvocationHandler();
//通过调用程序处理角色来处理我们要调用的接口对象
p.setRent(host);
Rent proxy = (Rent) p.getProxy();
proxy.rent();
}
}
public interface Rent {
public void rent();
}
public class Host implements Rent{
@Override
public void rent() {
System.out.println("出租房子~~~");
}
}
public class ProxyInvocationHandler implements InvocationHandler {
//代理接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(rent,args);
return result;
}
}
- 作者:麦克猫Cat
- 本文版权归作者和CSDN共有,欢迎交流