设计模式之代理模式-动态代理

文章介绍了Java中的动态代理机制,它是AOP(面向切面编程)的核心。动态代理在运行时生成,通过实现InvocationHandler接口并使用Proxy类的newProxyInstance方法创建。这种方式允许在不修改代理对象代码的情况下适应新需求,提高了代码的可维护性和可扩展性。虽然动态代理涉及反射和字节码生成,性能略逊于静态代理,但其优势更为显著。
摘要由CSDN通过智能技术生成
  1. 动态代理是在实现阶段不用关心代理谁,而在运行阶段 才指定代理哪一个对象。相对来说,自己写代理类的方式就是静态代理。本章节的核心部分 就在动态代理上,现在有一个非常流行的名称叫做面向横切面编程,也就是AOP(Aspect Oriented Programming),其核心就是采用了动态代理机制。

  1. 原理

  • 通过用户实现的InvocationHandler接口,获得真实处理事件的对象(相当于Proxy加了个传入真实实现对象监听);

  • 通过newProxyInstance传入的ClassLoader和一组Interface来创建动态代理类;

  • 通过反射获取动态代理类的构造方法,其构造函数的参数就是用户实现的InvocationHandler接口类;

  • 通过构造函数创建动态代理类实例。

  1. 优点:能够动态适配特定的代理场景,扩展性较好,符合软件工程的开闭原则

  1. 缺点:动态代理需要利用到反射机制和动态生成字节码,导致其性能会比静态代理稍差一些,但是相比于优点,这些劣势几乎可以忽略不计

  1. java中动态代理主要依靠InvocationHandler这个接口以及Proxy这个类的方法来实现。

动态代理是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

  1. 动态代理解决的问题是面对新的需求时,不需要修改代理对象的代码,只需要新增接口和真实对象,在客户端调用即可完成新的代理。

这样做的目的:满足软件工程的开闭原则,提高类的可维护性和可扩展性。

  1. 代码块

public interface ITeacherDap {
void teacher();
}
public class TeacherDao implements ITeacherDap{

@Override
public void teacher() {
   System.out.println("老师正在授课");
}

}
public class ProxyFactory {
//维护目标对象,object
private Object target;
//构造器,并且初始化target
public ProxyFactory(Object target) {
   super();
   this.target = target;
}
//给目标对象,生成代理对象
public Object getProxyInstance() {

   /*
   * public static Object newProxyInstance(ClassLoader loader,
                                        Class<?>[] interfaces,
                                        InvocationHandler h)
  */
   //ClassLoader loader指定当前目标对象使用的类加载器,获取加载器的方法固定
   // Class<?>[] interfaces目标对象的实现的接口类型,使用泛型方法确认类型
   //InvocationHandler h 事情处理,执行目标对象的方法时,触发事情处理方法,
   //会把当前执行的对象方法作为参数传入
   //loader
   //interfaces
   //h
   return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInt  erfaces(),
        new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("jdk代理开始");
                //通过反射机制调用目标对象的反射方法
                Object returnVal = method.invoke(target, args);
                System.out.println("jdk代理提交");
                return returnVal;
           }
    });
}
}
public class Clients {
public static void main(String[] args) {
   //创建目标对象
   ITeacherDap target = new TeacherDao();
   //给目标对象创建代理对象,转成ITeacherDap
   ITeacherDap p = (ITeacherDap)new ProxyFactory(target).getProxyInstance();
   //proxyinstance=class com.sun.proxy.$Proxy0内存中动态生成代理对象
    System.out.println("proxyinstance="+p.getClass());
   p.teacher();
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chuxuezhe_987

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值