动态代理实现原理

一,动态代理

首先,动态代理是代理模式的一种实现方式,代理模式除了动态代理还有 静态代理,只不过静态代理能够在编译时期确定类的执行对象,而动态代理只有在运行时才能够确定执行对象是谁。代理可以看作是对最终调用目标的一个封装,我们能够通过操作代理对象来调用目标类,这样就可以实现调用者和目标对象的解耦合。

动态代理的应用场景有很多,最常见的就是 AOP 的实现、RPC 远程调用、Java 注解对象获取、日志框架、全局性异常处理、事务处理等。动态代理的实现有很多,但是 JDK 动态代理是很重要的一种。

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。

JDK 动态代理

首先我们先来看一下动态代理的执行过程

 在 JDK 动态代理中,实现了 InvocationHandler 的类可以看作是 代理类(因为类也是一种对象,所以我们上面为了描述关系,把代理类形容成了代理对象)。JDK 动态代理就是围绕实现了 InvocationHandler 的代理类进行的,比如下面就是一个 InvocationHandler 的实现类,同时它也是一个代理类。

 1:InvocationHandler接口

接口中就一个方法 :invoke()
你的代理类要完成的功能就写在invoke()中

代理类需要完成的功能:

调用目标类的方法
功能增强,在目标方法调用时,增加功能,方法原型
Object proxy:jdk创建的代理对象,无需赋值
Method method:目标类中的方法
Object[] args:目标类中方法的参数
public Object invoke(Object proxy, Method method, Object[] args)

2:Method类

通过Method可以执行某个目标类的方法

3:proxy类

是最核心的一个类,使用静态方法 newProxyInstance() ,创建代理对象
方法原型:
ClassLoader loader:类加载器,负责向内存中加载对象(需要使用目标对象的类加载器)
Class<?>[] interfaces:目标对象实现的接口 InvocationHandler h:我们自己写的代理类需要实现的功能 返回值就是代理对象 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)

动态代理的实现步骤

  • 创建接口,定义目标类要完成的功能
public interface BookService {
    void sing(int a,double b);

    void dance();

    void rap();
}
public class CXK implements BookService {

    @Override
    public void sing(int a,double b) {
        System.out.println("唱歌"+a+"---"+b);
    }

    @Override
    public void dance() {
        System.out.println("跳舞");
    }

    @Override
    public void rap() {
        System.out.println("rap");
    }
}
  • 使用proxy类的newProxyInstance()方法,创建代理对象,并把返回值转成接口类型
public class Test01 {
    public static void main(String[] args) {
        BookService cxk = new CXK();

        BookService jjr = (BookService) Proxy.newProxyInstance(CXK.class.getClassLoader(), CXK.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                Object result = null;
                String name = method.getName();
                result=method.invoke(cxk,args);
                return result;
            }
        });
        jjr.sing(5,33.0);
        jjr.dance();
        jjr.rap();
    }
}

运行结果:

猜你喜欢

转载自blog.csdn.net/weixin_69036336/article/details/129823590
今日推荐