Java动态代理编码实现

本文介绍了Java动态代理技术,包括动态代理的概念、应用场景,如AOP编程、RPC框架、数据库连接池等,并通过实例展示了如何编码实现动态代理,包括简单动态代理和性能监控代理的实现,用于不改动原代码的情况下进行功能增强和性能监控。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第 1 章 Java动态代理介绍

1.1、动态代理介绍

Java动态代理是在运行时期动态生成代理对象的技术,通过代理对象可以在不改变原始代码的情况下,执行原始类的方法前后自定义的逻辑,对原始类方法的功能进行增强或拦截。

1.2、动态代理技术的应用场景

1、AOP编程:通过动态代理实现AOP编程,可以在不改变原有代码的情况下,实现对程序的横向扩展,比如日志记录、事务处理等。

2、RPC框架:通过动态代理可以实现远程方法调用,比如Dubbo、Spring Cloud等。

3、数据库连接池:通过动态代理可以实现数据库连接的池化,实现资源的重复利用,提高程序的性能。

4、消息中间件:通过动态代理可以实现消息的异步处理,比如Kafka、RocketMQ等。

5、权限控制:通过动态代理可以实现权限控制,比如在方法调用前进行权限校验,只有拥有权限的用户才能执行该方法。

6、缓存代理:通过动态代理可以实现缓存代理,将方法的返回值缓存起来,下次调用时可以直接返回缓存中的值,避免重复计算。

7、性能监控:通过动态代理可以实现性能监控,比如统计方法的执行时间、调用次数等信息,方便分析程序的性能瓶颈。

第 2 章 Java动态代理编码实现

代码在文档的最后~~~

2.1、简单动态代理编码实现

执行结果:

2.2、动态代理性能监控编码实现

需求背景:某系统有一个用户管理类,包含用户登录,删除用户,查询用户等功能,系统要求不修改原有代码的情况下统计每个功能的执行耗时情况,以便后期观察程序性能。

1、用户管理类代码

2、使用动态代理实现性能监控

3、程序执行结果

往期回顾

(37条消息) Postman接口测试项目实战_接口测试实战_春天播种秋天收获的博客-优快云博客

(37条消息) Oracle数据库和PLSQL可视化工具学习笔记_plsql工具介绍_春天播种秋天收获的博客-优快云博客

(37条消息) Python+Selenium自动化测试项目实战_selenium自动化测试实战基于python_春天播种秋天收获的博客-优快云博客

代码:

一、Cat代理业务

package net.yxclass.cat;

//1、定义接口
public interface Cat {
    void eat();
}

package net.yxclass.cat;

//2、定义代理目标对象
public class LazyCatImpl implements Cat {
    @Override
    public void eat() {
        System.out.println("如果不把饭放到嘴边就不吃饭啦~~~");
    }
}

package net.yxclass.cat;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//3、定义一个代理类,该代理类实现InvocationHandler接口,重写invoke方法。
public class CatProxy implements InvocationHandler {
    private Object target;

    public CatProxy(Object target) {
        this.target = target;
    }
    public static void preconditions() {
        System.out.println("把饭送到LazyCat的嘴边~~~");
    }
    public static void postWork() {
        System.out.println("LazyCat吃完饭后为他收拾餐具~~~");
    }

    //invoke方法,参数1:为代理的目标对象;参数2:代理目标对象的方法;参数3:代理目标对象方法的形参列表
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //在调用LazyCat吃饭方法前先调用代理对象把饭送到他的嘴边~~~
        preconditions();
        //LazyCat吃饭的方法
        Object invoke = method.invoke(target, args);
        //LazyCat吃完饭后为他收拾餐具~~~
        postWork();
        return invoke;
    }
}

package net.yxclass.cat;


import java.lang.reflect.Proxy;

//4、创建启动类
public class ProxyApp {
    public static void main(String[] args) {
        //创建代理的目标对象
        Cat cat = new LazyCatImpl();
        //创建InvocationHandler对象
        CatProxy catProxy = new CatProxy(cat);
        //创建代理对象
        Cat proxy = (Cat) Proxy.newProxyInstance(
                cat.getClass().getClassLoader(),// 获取原始对象的类加载器
                cat.getClass().getInterfaces(),// 获取原始对象实现的接口列表
                catProxy);// 传入代理对象的InvocationHandler对象
        //调用代理对象的方法
        proxy.eat();
    }
}

二、性能监控代理业务

package net.yxclass.admin;

// 用户业务接口
public interface UserService {
    // 登录功能
    void login(String loginName,String passWord) throws Exception;
    // 删除用户
    void deleteUsers() throws Exception;
    // 查询用户,返回数组的形式。
    String[] selectUsers() throws Exception;
}

package net.yxclass.admin;

// 用户业务实现类(面向接口编程)
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 deleteUsers() throws Exception{
        System.out.println("成功删除了1万个用户~");
        Thread.sleep(1500);
    }

    @Override
    public String[] selectUsers() throws Exception{
        System.out.println("查询出了3个用户");
        String[] names = {"令狐冲", "郭靖", "杨过"};
        Thread.sleep(500);
        return names;
    }
}

package net.yxclass.admin;

import java.lang.reflect.Proxy;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;

public class LoginApp {
    public static void main(String[] args) throws Exception {
        // 需求:为UserServiceImpl类创建一个代理对象---让代理对象来测试程序的性能
        // 创建UserServiceImpl的对象
        UserServiceImpl userService = new UserServiceImpl();

        // 获取类加载器
        ClassLoader classLoader = userService.getClass().getClassLoader();
        // 指定接口
        Class[] interfaces = {UserService.class};
        // 调用Proxy的newProxyInstance方法为userService创建一个代理对象,InvocationHandler是单函数式接口,所以使用Lambda表达式来写
        UserService proxy = (UserService) Proxy.newProxyInstance(classLoader, interfaces, (proxy1, method, args1) -> {
            // 只要代理对象调用方法就会来到这里执行
            // 在这里指定代理要做的事情
            if (method.getName().equals("login") || method.getName().equals("deleteUsers") || method.getName().equals("selectUsers")) {
                // 记录方法调用前的时间
                Instant now1 = Instant.now();
                // 执行被代理对象的login方法
                Object res = method.invoke(userService, args1);
                // 记录方法执行完成后的时间
                Instant now2 = Instant.now();
                //计算方法执行时长
                Duration betweenTime = Duration.between(now1, now2);
                System.out.println(method.getName() + "方法耗时:" + betweenTime);
                return res;
            }
            Object res = method.invoke(userService, args1);
            return res;
        });

        // 吩咐代理做事情
        proxy.login("admin", "123456");
        System.out.println("---------------");
        proxy.deleteUsers();
        System.out.println("----------------");
        String[] users = proxy.selectUsers();
        System.out.println("users:  " + Arrays.toString(users));
        System.out.println("----------------");

        // 不需要代理做其他事情,只需要代理叫被代理对象来执行toString方法
        String res = proxy.toString();
        System.out.println("res = " + res);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

远方的音讯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值