动态代理的理解(用简单例子来表示)

什么是动态代理

动态代理是在程序运行时生成代理对象,而不是在编译时确定。在 Java 中,动态代理通常使用 Java 反射机制实现。Java 提供了 java.lang.reflect 包,其中的 Proxy 类和 InvocationHandler 接口是实现动态代理的关键。

动态代理的核心思想是,通过一个代理类,实现 InvocationHandler 接口,动态生成代理对象。代理对象在运行时负责处理被代理对象的方法调用,并可以在方法调用前后执行额外的逻辑。

我的个人理解:动态代理的作用其实就是为了在不删改原有的代码基础上,为对象添加新的行为或功能

举一个测试的例子

现在公司有个增删改查,需要让你在增删改查每个方法添加一个日志

但是不能改变原有代码,因为有时候改变原有代码会出现一些莫名其妙的bug

这就是开闭原则,是面向对象设计中的一个基本原则

1.首先要有个接口

public interface UserService {
    public void add();
    public void update();
    public void delete();
    public void query();
}

2.实现这个接口

public class UserServiceImpl implements UserService {
    @Override
    public void add() {
        System.out.println("add");
    }
​
    @Override
    public void update() {
        System.out.println("update");
    }
​
    @Override
    public void delete() {
        System.out.println("delete");
    }
​
    @Override
    public void query() {
        System.out.println("query");
    }
}

动态代理类(实现InvocationHandler接口)

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
​
public class UserServiceProxy implements InvocationHandler {
    //这是为了代理任何对象  被代理对象
    Object target;
    //当传入什么实现类,就会代理哪个实现类 方法名随便
    public void setUserService(Object target) {
        this.target = target;
    }
​
    public Object getProxy()
    {
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),                                                 target.getClass().getInterfaces()
                                      ,this);
    }
​
​
    @Override
    public Object invoke(Object o, Method method, Object[] args) throws Throwable {
        log(method.getName());
        method.invoke(target,args);
        return null;
    }
    public void log(String msg)
    {
        System.out.println(msg);
    }
}
​
详解 Proxy.newProxyInstance()这个方法
  
  public Object getProxy()
    {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
    }

方法的第一个参数用于获取被代理对象的所有属性

传入被代理对象的类加载器

类加载器确保新生成的代理对象能够访问目标对象的类

第二个参数是为了实现和被代理类相同的接口:

传入被代理对象所实现的接口

获取目标对象所实现的接口。这是为了确保代理对象实现了与目标对象相同的接口,从而可以代理相同的方法

第三个参数this 关键字表示当前对象,即 UserServiceProxy 对象。

传入this 这个是死的

UserServiceProxy 实现了 InvocationHandler 接口,所以它可以作为代理对象的 InvocationHandler

写getProxy方法的作用:

为了处理invoke的第一个参数object 也就是这是谁的代理对象。

详解invoke方法
@Override
    public Object invoke(Object o, Method method, Object[] args) throws Throwable {
        log(method.getName());
        method.invoke(target,args);
        return null;
    }
第一个参数

不用填 因为getProxy已经做了

代理对象,即通过 Proxy.newProxyInstance 方法生成的代理对象。在 invoke 方法中,你可以使用这个对象来调用被代理对象的方法。

第二个参数

传入被代理对象

被代理对象的方法。通过这个参数,你可以获取方法的名称、参数、返回类型等信息。

第三个参数

方法的参数数组。这是被代理方法调用时传递的参数。

method.invoke(target, args):

这一行使用 method.invoke 调用了被代理对象(target)的方法。通过传递 args 数组作为参数,实际执行了被代理方法。这是在执行被代理方法的地方。

测试类(测试是否增加方法)

public class Client {
    public static void main(String[] args) {
       UserServiceProxy userServiceProxy = new UserServiceProxy();
       UserServiceImpl userService = new UserServiceImpl();
​
•       userServiceProxy.setUserService(userService);
•        UserService proxy = (UserService) userServiceProxy.getProxy();
•        proxy.add();
•    }
}

中文有乱码 不知道什么动态代理的理解(用简单例子来表示)_第1张图片情况 总之原理是这样

你可能感兴趣的:(javaSE,spring,java,开发语言,spring)