代理模式
用一个类 代替另一个类的功能,并实现控制 属于结构型模式
优点
1、职责清晰
2、高扩展性
案例
// 假设我们现在要租一套四室一厅的房子
public class RentHouse {
public void renthouse(){
System.out.println("租房子 4室 1厅");
}
// 自己找太麻烦了,我们就找到了一个中介(代理),由他出面帮我们找房子
// 我们需要将自己的需求告诉他,找到房子后,我们交钱就完事了
静态代理模式
public class ProxyRentHouse {
// 持有需要被代理的对象
private RentHouse rentHouse;
public ProxyRentHouse(RentHouse rentHouse){
this.rentHouse = rentHouse;
}
public void renthouse(){
System.out.println("收取代理费");
rentHouse.renthouse();
System.out.println("收取好处费");
}
}
public class RentTest {
public static void main(String[] args) {
RentHouse rentHouse = new RentHouse();
// rentHouse.renthouse();
ProxyRentHouse proxyRentHouse = new ProxyRentHouse(rentHouse);
proxyRentHouse.renthouse();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cv5CXrVp-1624593589938)(D:\Learning\笔记\学习笔记\设计模式\代理模式\代理模式.assets\image-20210625111307193.png)]
// 自从上次找代理 帮我们找房子之后觉得很轻松,所以我们后续好多好多事情都想着找代理,但是这个时候,代理会越来越多,我们能不能只找一个代理,让他动态的为我们去做事情呢。
动态代理模式
jdk动态代理
public Object getJdkInstance(Object obj){
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("交代理费啊~~~");
Object result = method.invoke(obj, args);
System.out.println("干活完了给点好处费啊~~~~");
return result;
}
});
}
// 这里假设我们直接运行会报错,因为我的租房方法没有定义接口。这也是jdk动态代理和 cglib动态代理最大的区别,jdk动态代理要求被代理对象必须有接口 因为在newProxyInstance中有这个参数
cglib动态代理
/**
需要导入jar
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency>
*/
public Object getCglibInstance(Object obj){
return Enhancer.create(obj.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("交代理费啊cglib~~~");
Object result = method.invoke(obj,objects);
System.out.println("干活完了给点好处费啊cglib~~~");
return result;
}
});
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7NlQglGf-1624593589940)(D:\Learning\笔记\学习笔记\设计模式\代理模式\代理模式.assets\image-20210625114546747.png)]
// 这时我们想要买房子 直接告诉他我想买就行了
public class RentTest {
public static void main(String[] args) {
// RentHouse rentHouse = new RentHouse();
BuyHouse buyHouse = new BuyHouse();
// rentHouse.renthouse();
// ProxyRentHouse proxyRentHouse = new ProxyRentHouse(rentHouse);
// proxyRentHouse.renthouse();
ProxyFactory proxyFactory = new ProxyFactory();
IBuyHouse jdkInstance = (IBuyHouse) proxyFactory.getJdkInstance(buyHouse);
jdkInstance.buyhouse();
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-waDx8jzG-1624593589943)(D:\Learning\笔记\学习笔记\设计模式\代理模式\代理模式.assets\image-20210625115830120.png)]