动态代理(通俗易懂)

目录

一、程序为什么需要代理?代理长什么样?

二、实际例子

1.实体类,被代理的对象

2.代理对象(接口)

3.代理工具类 

4.测试类

5.输出

三、解决实际问题

1.UserService

2.UserServiceImpl

3.ProxyUtil

4.TestProxy

5.输出


一、程序为什么需要代理?代理长什么样?

二、实际例子

梳理

  • 代理对象(接口):要包含被代理的对象的方法 ---Star

  • 被代理对象:要实现代理对象(接口) ---SuperStar

  • 代理工具类:创建一个代理,返回值用代理对象,参数传被代理的对象,用Proxy代理类new一个实例,并重写invoke方法 --- 就是代理对象要做的事情

superStar在唱之前的准备工作交给代理Star去做,比如果说superStar要唱歌,就让代理去申请场地等,同时这个代理对象Star要有superStart的方法(唱歌等),而superStar要实现代理对象start(接口),代理工具类ProxyUtil中写创建代理的方法,参数传superStar,返回值为Star,这个方法中写代理的对象要做的事情。

1.实体类,被代理的对象

(要实现代理)


package com.dev.springBootDemo.proxy;

/**
 * @author zhumq
 * @date 2024/7/2 20:51
 */
public class SuperStar implements Star{
    private String name;

    public SuperStar(String name) {
        this.name = name;
    }

    public String sing(String singName) {
        System.out.println(this.name + "正在唱:" + singName);
        return "唱完了!谢谢大家!";
    }

    public void dance() {
        System.out.println(this.name + "正在跳舞中~~~" );
    }

}
 

2.代理对象(接口)

要包含被代理的对象的方法

package com.dev.springBootDemo.proxy;

/**
 * @author zhumq
 * @date 2024/7/2 20:56
 */
public interface Star {
    void dance();
    String sing(String singName);
}

3.代理工具类 

创建一个代理,返回值用代理对象,参数传被代理的对象,用Proxy代理类new一个实例,并重写invoke方法 --- 就是代理对象要做的事情

package com.dev.springBootDemo.proxy;
​
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
​
/**
 * @author zhumq
 * @date 2024/7/2 20:57
 */
public class ProxyUtil {
    public static Star createProxy(SuperStar superStar) {
        /**
         * (lassLoader loader , Class<?>[] interfaces, InvocationHandler h )
         * 参数1:用于指定一个类加载器
         * 参数2:用于指定一个接口数组,因为一个代理类可以代理多个接口,所以可以指定多个接口
         *       也就是指定生成的代理长什么样
         * 参数3:用于指定一个InvocationHandler对象,当调用代理类的方法时,就会自动调用InvocationHandler中的invoke方法
         *       (指定InvocationHandler中的invoke方法,在调用Star接口中的方法时,就会自动执行)
         *       也就是生成的代理对象要做什么
         }
         */
        Star starProxy = (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(superStar, args);
                    }
                });
        return starProxy;
    }
}
​

4.测试类

package com.dev.springBootDemo.proxy;
​
/**
 * @author zhumq
 * @date 2024/7/2 21:16
 */
public class TestProxy {
    public static void main(String[] args) {
        SuperStar superStar = new SuperStar("周杰伦");
        Star proxy = ProxyUtil.createProxy(superStar);
        System.out.println(proxy.sing("稻香"));
        proxy.dance();
    }
}

5.输出

代理要去做:唱歌要先租场地
周杰伦正在唱:稻香
唱完了!谢谢大家!
代理要去做:跳舞要去请老师教
周杰伦正在跳舞中~~~

三、解决实际问题

  • UserService

  • UserServiceImpl

  • ProxyUtil

  • TestProxy

1.UserService

package com.dev.springBootDemo.proxy2;

/**
 * 用户业务接口
 * @author zhumq
 * @date 2024/7/2 21:33
 */
public interface UserService {
    // 登录功能
    void login(String loginName, String password) throws Exception;
    // 删除用户功能
    void deleteUser() throws Exception;
    // 查询用户功能
    String[] selectUsers() throws Exception;
}

2.UserServiceImpl

package com.dev.springBootDemo.proxy2;
​
/**
 * 用户业务实现(面向接口编程鸟纲)
 * @author zhumq
 * @date 2024/7/2 21:35
 */
public class UserServiceImpl implements UserService{
    @Override
    public void login(String loginName, String password) throws Exception {
​
        if ("admin".equals(loginName) && "123456".equals(password)) {
            System.out.println("登录成功");
        }else {
            System.out.println("登录失败");
        }
        Thread.sleep(1000);
    }
​
    @Override
    public void deleteUser() throws Exception {
        System.out.println("删除了10个用户");
        Thread.sleep(1000);
​
    }
​
    @Override
    public String[] selectUsers() throws Exception {
        System.out.println("查询了2个用户");
        String[] users = new String[]{"张三", "李四"};
        Thread.sleep(1000);
        return users;
    }
}

3.ProxyUtil

package com.dev.springBootDemo.proxy2;
​
import com.dev.springBootDemo.proxy.Star;
​
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
​
/**
 * @author zhumq
 * @date 2024/7/2 21:41
 */
public class ProxyUtil {
    // 为用户业务对象创建代理
    public static UserService createProxy(UserService userService) {
        UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(), new Class[]{UserService.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if ("login".equals(method.getName()) || "deleteUser".equals(method.getName())
                        || "selectUsers".equals(method.getName())) {
​
                    long startTime = System.currentTimeMillis();
​
                    Object s = method.invoke(userService, args);
​
                    long endTime = System.currentTimeMillis();
​
                    System.out.println(method.getName() + "方法耗时:" + (endTime - startTime) / 1000 + "s");
​
                    return s;
                } else {
                    return method.invoke(userService, args);
                }
            }
        });
        return userServiceProxy;
    }
}

4.TestProxy

package com.dev.springBootDemo.proxy2;
​
import java.util.Arrays;
​
/**
 * @author zhumq
 * @date 2024/7/2 21:49
 */
public class TestProxy {
    public static void main(String[] args) throws Exception {
        UserService userService = ProxyUtil.createProxy(new UserServiceImpl());
​
        System.out.println("----------------用户登录-------------------");
        userService.login("admin", "123456");
        System.out.println("----------------用户删除-------------------");
        userService.deleteUser();
        System.out.println("----------------用户查询-------------------");
        String[] users = userService.selectUsers();
        System.out.println(Arrays.toString(users));
    }
}

5.输出

----------------用户登录-------------------
登录成功
login方法耗时:1s
----------------用户删除-------------------
删除了10个用户
deleteUser方法耗时:1s
----------------用户查询-------------------
查询了2个用户
selectUsers方法耗时:1s
[张三, 李四]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

伏颜.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值