Java动态代理

发布时间:2024年01月04日

1.什么是代理?

????????编程中的代理是指:使用一个对象对另一个对象进行管理。

????????包括两种,一种是数据代理,即使用一个对象对另外一个或者多个对象的数据进行管理,典型的例子就是Vue框架,使用一个Vue总对象管理大量子对象的数据,然后渲染到HTML页面。

? ? ? ? 另一种就是方法代理。这种做法就是使用一个对象对另一个对象的方法进行统一管理并且可以给管理的方法添加新的功能,从而避免侵入式修改。

? ? ? ? 所以代理的基本前提就是:存在两个对象A和B,利用A对象去管理B对象的方法。而Java的基本单位是类,所以代理一般都是把被代理的对象B当作数据封装在一个类中,然后用这个类的实例对象A去管理对象B。

????????而根据Java的特性,实现动态代理必须手动实现一个接口Interface来定义需要被代理的方法,即决定代理对象长啥样。同时,被代理的对象B需要实现这个接口。

? ? ? ? 但是,在Java中,通常使用API接口来实现动态代理,从而避免创造过多的代理类。这个API就是Proxy.newProxyInstance

2.java.lang.reflect.Proxy类的newProxyInstance静态方法

????????Proxy.newProxyInstance静态方法返回一个代理对象,也就是上面的对象A。Proxy.newProxyInstance静态方法有3个参数,如下所示:

Proxy.newProxyInstance(Proxyutils.class.getClassLoader(), //使用Proxyutils类的类加载器去加载这个代理类
            new Class[]{Star.class}, //接口的字节码class对象,需要代理的方法都需要写在这个接口里面,同时被代理对象也需要实现这个接口。
            // InvocationHandler接口的实现类的类实例对象,需要根据代理任务的不同从而每次手动实现这个接口
            new InvocationHandler(){
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return null;
            }})

3.代码部分——类实现

? ? ? ? 使用一个类进行封装并实现。使用时,修改相应的类名和接口名就行了。

import java.lang.reflect.*;
public class BigstarProxy {

    //需要代理的对象
    private Bigstar star;
    //返回的代理对象,他是Star接口实现类的一个实例对象,这个Star类需要手动实现提供,里边包含需要增加额外功能的方法
    private Star wrapBigstar;
    // 需要代理的额外逻辑内容
    private InvocationHandler invoke_handler = new InvocationHandler(){
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                
                // 通过method方法对象的name属性来识别方法对象,以选择指定分支对方法进行修饰
                if("sing".equals(method.getName())){
                    System.out.println("准备话筒,收钱");
                }else if("dance".equals(method.getName())){
                    System.out.println("准备场地,收钱");
                };

                // 在执行上面的代码之后,下面的代码会去调用被代理对象的方法,实现在被代理方法执行之前先处理一些事情
                return method.invoke(star,args);
                // 也可以先调用被代理对象的方法,在执行另外需要处理的代码
            }};

    public BigstarProxy(Bigstar star){
        this.star = star; 
    }

    // 通过这个方法获取代理对象
    public Star get_wrap_Proxy_Obj(){
        this.getProxy_Star();
        return this.wrapBigstar;
    }

    private void getProxy_Star(){
        this.wrapBigstar = (Star) Proxy.newProxyInstance(
            BigstarProxy.class.getClassLoader(),
            new Class[]{Star.class},
            this.invoke_handler
            );
    }
    
}

4.代码部分——API接口实现

        Star star = (Star) Proxy.newProxyInstance(
                ProxyUtil.class.getClassLoader(),//参数一:用于指定用哪个类加载器,去加载生成的代理类
                new Class[]{Star.class},//参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
                //参数三:用来指定生成的代理对象要干什么事情
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         
                        if("sing".equals(method.getName())){
                            System.out.println("准备话筒,收钱");
                        }else if("dance".equals(method.getName())){
                            System.out.println("准备场地,收钱");
                        }
 
                        return method.invoke(bigStar,args);
                    }
                }
        );
    // 使用代理对象调用方法就行了
    star.xxxmethods();

? ? ? ? 新手刚学,有错误烦请指正。

文章来源:https://blog.csdn.net/weixin_44992737/article/details/135387428
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。