Java设计模式 ---- 代理模式

柔光的暖阳◎ 2022-05-25 11:09 264阅读 0赞

一,代理模式

  1. 为其他对象提供一种代理以控制对这个对象的访问。代理模式可以分为静态代理和动态代理模式,动态代理也有通过JDK实现的动态代理模式和CGLib实现的动态代理,下面将分别展示。

二,UML图

70

Subject : 定义了RealSubject和Proxy的共同接口,这样可以在应用过程中通过多态实现接口公用;

RealSubject : 定义Proxy所要代理的真是实体;

Proxy : RealSubject实体的代理类,可以通过实体生成代理对象实现对实体的控制访问;

Proxy和RealSubject之间没有绝对的强一致关系,可以不需要共同实现一个接口实现多态;

三,静态代理模式

  1. 静态代理模式更多的体现在接口的调用,不多做分析,只做一个简单的展示

1,实体类

  1. public class StaticTarget {
  2. public void targetMethod() {
  3. System.out.println("被代理的方法");
  4. }
  5. }

2,代理类

  1. public class StaticProxy {
  2. private StaticTarget staticTarget;
  3. public StaticProxy(StaticTarget staticTarget) {
  4. this.staticTarget = staticTarget;
  5. }
  6. public void proxyMethod() {
  7. System.out.println("开始代理...");
  8. staticTarget.targetMethod();
  9. System.out.println("结束代理...");
  10. }
  11. }

3,客户端

  1. public class StaticProxyTest {
  2. public static void main(String[] args) {
  3. StaticTarget target = new StaticTarget();
  4. StaticProxy proxy = new StaticProxy(target);
  5. proxy.proxyMethod();
  6. }
  7. }

四,动态代理_JDK实现

  1. JDK实现的动态代理,被代理类也就是实体类必须实现一个接口,这样会与JDK生成的虚拟代理类存在强一致性关系,从而形成多态调用。

1,顶层接口

  1. public interface ProxyInterface {
  2. public void targetMethod();
  3. }

2,实体类 — 实现顶层接口

  1. public class JDKProxyTarget implements ProxyInterface{
  2. @Override
  3. public void targetMethod() {
  4. System.out.println("代理方法...");
  5. }
  6. }

3,代理对象生成

  1. 该类只负责生成代理对象,具体代理对象的方法调用。JDK在生成代理对象时,也会生成一个该代理对象所属的.class文件。所return的接口对象实际数据该代理类的对象,通过多态调用,所调用的方法为该虚拟类内部的方法,这一块内容将在手写JDK动态代理中分析;
  2. public class JDKProxy {
  3. private ProxyInterface proxyInterface;
  4. public JDKProxy(ProxyInterface proxyInterface) {
  5. this.proxyInterface = proxyInterface;
  6. }
  7. public Object instanceProxy() {
  8. System.out.println("代理方法开始...");
  9. ProxyInterface instance = (ProxyInterface) Proxy.newProxyInstance(
  10. proxyInterface.getClass().getClassLoader(),
  11. proxyInterface.getClass().getInterfaces(),
  12. new InvocationHandler() {
  13. @Override
  14. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  15. method.invoke(proxyInterface, args);
  16. System.out.println("代理方法结束...");
  17. return null;
  18. }
  19. });
  20. return instance;
  21. }
  22. }
  23. \* 该代理对象生成类会先获取实体类的引用,通过该实体类来生成对应的代理类和代理对象;
  24. \* newInstance()(自定义方法)方法中,通过调用JDK所提供的Proxy对象来获取代理对象;

* 在JDK提供的newProxyInstance()中,需要依次传入实体对象的类加载器,类实现的所有接口和InvocationHandler的实现类对象,这里通过匿名内部类获取;

  1. \* InvocationHandler的实现类会重写该接口的invoke()方法,也是整个动态代理最终执行方法的位置,method就是客户端所执行的方法,通过反射方式执行;

4,客户端

  1. public class JDKProxyTest {
  2. public static void main(String[] args) {
  3. JDKProxy proxy = new JDKProxy(new JDKProxyTarget());
  4. ProxyInterface proxyInterface = (ProxyInterface) proxy.instanceProxy();
  5. System.out.println(proxyInterface.getClass());
  6. proxyInterface.targetMethod();
  7. }
  8. }

5,执行接口

70 1

  1. 从控制台结果中可以看出,所生成的proxyInterface对象,并不属性原来的实体类,而是JDK自动生成的$Proxy0类。

五,动态代理_CGLib方式

  1. JDK代理模式在结构上不同的是
  2. \* 实体类不需要继承或者实现任何类和接口,不存在强一致性关系
  3. \* 代理类必须实现MethodInterceptor接口并实现interceptor()方法,

1,实体类

  1. public class CglibTarget {
  2. public void targetMethod() {
  3. System.out.println("代理方法...");
  4. }
  5. }

2,代理类

  1. public class CglibProxy implements MethodInterceptor{
  2. public Object instanceProcy(Class<?> clazz) {
  3. Enhancer enhancer = new Enhancer();
  4. enhancer.setSuperclass(clazz);
  5. enhancer.setCallback(this);
  6. return enhancer.create();
  7. }
  8. @Override
  9. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  10. System.out.println("代理前...");
  11. Object result = methodProxy.invokeSuper(o, objects);
  12. System.out.println("代理后...");
  13. return result;
  14. }
  15. }
  16. \* 该代理类,在instanceProcy()方法中,通过Enhancer创建出目标类的代理对象;
  17. \* 在实现的intercept()方法中,通过反射进行完成调用;

3,客户端

  1. public class CglibProxyTest {
  2. public static void main(String[] args) {
  3. CglibProxy cglibProxy = new CglibProxy();
  4. CglibTarget proxy = (CglibTarget)cglibProxy.instanceProcy(CglibTarget.class);
  5. proxy.targetMethod();
  6. }
  7. }

70 2

发表评论

表情:
评论列表 (有 0 条评论,264人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java设计模式代理模式

    什么是代理模式?   对于一个类的方法的调用,不直接通过该类的对象来调用方法,程序里有一个专门的代理类,通过调用代理类的方法来实现真实类内部方法的调用。   特征是:代理类