浅谈代理模式(一)

编程入门 行业动态 更新时间:2024-10-08 04:23:46

<a href=https://www.elefans.com/category/jswz/34/1769825.html style=浅谈代理模式(一)"/>

浅谈代理模式(一)

代理模式基础

代理模式基础

  • 代理模式是在框架设计中经常使用的一种设计模式。

首先代理模式,可以分为两种,一种是静态代理,一种是动态代理。

  • 代理模式属于结构型设计模式。
  • 它的作用是为其他对象提供一层代理以控制对类的访问,当我们无法直接访问某一个类时可使用代理模式作为中介。

两种代理从虚拟机加载类的角度来讲,本质上都是一样的,都是在原有类的行为基础上,加入一些多出的行为,甚至完全替换原有的行为。

  • 代理类和委托类必须实现同一接口。

动态代理有一个强制性要求,就是被代理的类必须实现了某一个接口,或者本身就是接口,就像我们mybatis中的Mapper。

  • 代理模式的优点 :可以在不修改委托类的情况下,为委托类提供新的功能,符合开闭原则。
  • 代理模式的应用场景 :
    1. 为委托类添加统一处理,例如Spring的AOP。
    2. 提供统一快捷的请求访问,例如mybatis的mapper,spring cloud的feign等等。

静态代理模式

代理模式类图

应用场景和代码实现

现在公司接到一个新项目,老板需要吩咐下面去完成它,一般来说,老板不会亲自去吩咐程序员写代码,而是将项目事宜交给项目经理,由项目经理统一调度,接下来我们实现这个过程。

公司职员接口
public interface Employee {void work();
}
码农
public class Programmer implements Employee {//码农的本职工作就是写代码@Overridepublic void work(){System.out.println("写代码");}
}
项目经理
public class ProjectManager implements Employee {private final Programer programmer;public ProjectManager(){//项目经理选择程序员programmer = new Programmer();}@Overridepublic void work(){System.out.println("项目经理说明项目");this.programmer.work();System.out.println("项目经理验收项目");}
}

这样就完成了一个静态代理模式的过程,总的来说静态代理模式非常简单,就是代理类和委托类实现同样的接口,一切的工作就有代理类来完成,与装饰器模式不同的是,使用者不需要关心委托类的任何操作,只需要跟代理类进行交互就可以了。
一般来说在代理类数量固定,并不太多时,建议使用静态代理,因为动态代理需要在运行时动态生成代理类,会相对较慢。

JDK动态代理

动态代理类图


当我们需要代理一系列类的某些方法时,很显然静态代理就无法满足我们的需求了,我们不能为每一个类型的委托类,创建一个专用的代理类,这时,我们就可以使用动态代理来完成我们的功能。

代码实现

常规日志
public interface IEmployee {String work(String str);
}
public class Programmer implements IEmployee {@Overridepublic String work(String str) {System.out.println(str+"is coding");}
}
public class ProductManager implements InvocationHandler {public IEmployee employee;public ProductManager(IEmployee employee){this.employee = employee;}@Overridepublic Object invoke(Object obj, Method method, Object[] args) {System.out.println("项目经理发布任务");Object result = method.invoke(employee, args);System.out.println("项目经理收集成果");return result;}public static void main(String[] args){IEmployee programmer = new Programmer();Proxy.newProxyInstance(programmer.getClass().getClassLoader(),programmer.getClass().getInterfaces(),new ProductManager());}
}
接口实现式
public interface Mapper {Object selectById(Integer id);
}
public class SessionManager {public static <T>T getMapper(Class<T> mapper) {T t = (T)Proxy.newProxyInstance(SessionManager.class.getClassLoader(), new Class[]{mapper}, (proxy,method,args)-> {if("selectById".equals(method.getName())){return "Arthur is " + args[0];}return null;});return t;}public static void main(String[] args){PersonMapper personMapper = SessionManager.getMapper(PersonMapper.class);System.out.println(personMapper.selectById(2));}
}
AOP
public interface IAdvice {void exec();
}
public class BeforeAdivice implements IAdvice{@Overridepublic void exec() {System.out.println("执行前置通知");}
}
public class AfterAdvice implements IAdvice{@Overridepublic void exec() {System.out.println("执行前置通知");}
}
public class ProxyManager implements InvocationHandler {private Object object;public ProxyManager(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {IAdvice beforeAdvice = new BeforeAdivice();beforeAdvice.exec();method.invoke(object, args);IAdvice afterAdvice = new AfterAdvice();afterAdvice.exec();return null;}public static void main(String[] args) {Test test = new TestImpl();Test proxy = (Test) Proxy.newProxyInstance(ProxyManager.class.getClassLoader(), new Class[]{Test.class}, new ProxyManager(test));proxy.show();}
}
public interface Test {void show();
}
public class TestImpl implements Test{@Overridepublic void show() {System.out.println("这是一个悲惨的方法");}
}

更多推荐

浅谈代理模式(一)

本文发布于:2024-02-07 02:56:29,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1752519.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:浅谈   模式

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!