动态代理

动态代理

模拟企业业务功能开发,并完成每个功能的性能统计
需求
模拟某企业用户管理业务,需包含用户登录,用户删除,用户查询功能,并要统计每个功能的耗时。
分析
定义一个UserService表示用户业务接口,规定必须完成用户登录,用户删除,用户查询功能。
定义一个实现类UserServiceImpl实现UserService,并完成相关功能,且统计每个功能的耗时。
定义测试类,创建实现类对象,调用方法。

package com.itheima.d9_proxy;

/**
   模拟用户业务功能
 */
public interface UserService {
    String login(String loginName , String passWord) ;
    void selectUsers();
    boolean deleteUsers();
    void updateUsers();
}

 

package com.itheima.proxy;

public class UserServiceImpl implements UserService {
    @Override
    public String login(String loginName, String passWord)  {
        long startTimer = System .currentTimeMillis();
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long endTimer = System.currentTimeMillis();
        System.out.println("login"+"方法耗时:" + (endTimer - startTimer) / 1000.0 + "s");
        if("admin".equals(loginName) && "1234".equals(passWord)) {
            return "success";
        }

        return "登录名和密码可能有毛病";

    }

    @Override
    public void selectUsers() {
        long startTimer = System .currentTimeMillis();
        System.out.println("查询了100个用户数据!");
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long endTimer = System.currentTimeMillis();
        System.out.println("selectUsers"+"方法耗时:" + (endTimer - startTimer) / 1000.0 + "s");
    }

    @Override
    public boolean deleteUsers() {
        long startTimer = System .currentTimeMillis();
        try {
            System.out.println("删除100个用户数据!");
            Thread.sleep(500);
            long endTimer = System.currentTimeMillis();
            System.out.println("deleteUsers"+"方法耗时:" + (endTimer - startTimer) / 1000.0 + "s");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    @Override
    public void updateUsers() {
        long startTimer = System .currentTimeMillis();
        try {
            System.out.println("修改100个用户数据!");
            Thread.sleep(2500);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long endTimer = System.currentTimeMillis();
        System.out.println("updateUsers"+"方法耗时:" + (endTimer - startTimer) / 1000.0 + "s");
    }
}

 

package com.itheima.proxy;


public class Test {
    public static void main(String[] args) {
        // 1、把业务对象,直接做成一个代理对象返回,代理对象的类型也是 UserService类型
        UserService userService=new UserServiceImpl();
        System.out.println(userService.login("admin", "1234"));
        System.out.println(userService.deleteUsers());
        userService.selectUsers();
        userService.updateUsers(); // 走代理
    }
}

 

login方法耗时:1.005s
success
删除100个用户数据!
deleteUsers方法耗时:0.505s
true
查询了100个用户数据!
selectUsers方法耗时:2.002s
修改100个用户数据!
updateUsers方法耗时:2.502s

 

其中的

long startTimer = System .currentTimeMillis();
long endTimer = System.currentTimeMillis();
System.out.println("login"+"方法耗时:" + (endTimer - startTimer) / 1000.0 + "s");

每个方法都会重复调用

这可以用动态代理去实现

package com.itheima.d9_proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
    public static Object newProxyInstance(ClassLoader loader,  Class<?>[] interfaces, InvocationHandler h)
    参数一:类加载器,负责加载代理类到内存中使用。
    参数二:获取被代理对象实现的全部接口。代理要为全部接口的全部方法进行代理
    参数三:代理的核心处理逻辑
 */
public class ProxyUtil {
    /**
      生成业务对象的代理对象。
     * @param obj
     * @return
     */
    public static <T> T  getProxy(T obj) {
        // 返回了一个代理对象了
        return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 参数一:代理对象本身。一般不管
                        // 参数二:正在被代理的方法
                        // 参数三:被代理方法,应该传入的参数
                       long startTimer = System .currentTimeMillis();
                        // 马上触发方法的真正执行。(触发真正的业务功能)
                        Object result = method.invoke(obj, args);

                        long endTimer = System.currentTimeMillis();
                        System.out.println(method.getName() + "方法耗时:" + (endTimer - startTimer) / 1000.0 + "s");

                        // 把业务功能方法执行的结果返回给调用者
                        return result;
                    }
                });
    }
}

 

package com.itheima.d9_proxy;

public class Test {
    public static void main(String[] args) {
        // 1、把业务对象,直接做成一个代理对象返回,代理对象的类型也是 UserService类型
        UserService userService = ProxyUtil.getProxy(new UserServiceImpl());
        System.out.println(userService.login("admin", "1234"));
        System.out.println(userService.deleteUsers());
        userService.selectUsers();
        userService.updateUsers(); // 走代理
    }
}

  

posted @ 2022-12-01 10:27  __破  阅读(37)  评论(0)    收藏  举报