Java动态代理简单应用
作者:网络转载 发布时间:[ 2015/10/10 13:32:32 ] 推荐标签:编程语言 测试开发技术
方法性能监测
监测方法运行性能效率,此处简单以方法运行时间作为评价标准。传统的做法是在每个方法执行前后各自记录时间,然后计算运行时间。采用动态代理机制,可以将以上操作统一到InvocationHandler中,并创建代理类监测所有的方法。
InvocationHandler实现类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PerformanceInterceptor implements InvocationHandler {
private Object proxied;
public PerformanceInterceptor(Object proxied) {
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
Object obj = method.invoke(proxied, args);
long endTime = System.currentTimeMillis();
System.out.println("Method " + method.getName() + " execution time: " + (endTime - startTime) * 1.0 / 1000 + "s");
return obj;
}
}
测试类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import org.junit.Test;
public class PerformanceInterceptorTest {
@Test
public void testInvoke() {
UserDao userDao = new UserDaoImpl();
Class<?> cls = userDao.getClass();
InvocationHandler handler = new PerformanceInterceptor(userDao);
UserDao proxy = (UserDao) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), handler);
proxy.addUser(new User("tom"));
proxy.deleteUser("tom");
proxy.updateUser("tom");
}
}
测试结果
add user named Tom...
Method addUser execution time: 1.0s
delete user named tom...
Method deleteUser execution time: 1.5s
update user named tom...
Method updateUser execution time: 2.0s
日志管理
有时候开发者需要在方法开始执行和执行结束时打印一些信息,使用动态代理可以对所有方法或者某些方法进行简单日志管理,并写入到指定文件。
InvocationHandler实现类
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class LogInterceptor implements InvocationHandler {
private Object proxied;
public static final String path = "run.log";
public LogInterceptor(Object proxied) {
this.proxied = proxied;
}
public String beforeMethod(Method method) {
return getFormatedTime() + " Method:" + method.getName() + " start running ";
}
public String afterMethod(Method method) {
return getFormatedTime() + " Method:" + method.getName() + " end running ";
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
write(path, beforeMethod(method));
Object object = method.invoke(proxied, args);
write(path, afterMethod(method));
return object;
}
public String getFormatedTime() {
DateFormat formater = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
return formater.format(System.currentTimeMillis());
}
public void write(String path, String content) {
FileWriter writer = null;
try {
writer = new FileWriter(new File(path), true);
writer.write(content);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null != writer) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
测试类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import org.junit.Test;
public class LogInterceptorTest {
@Test
public void testInvoke() {
UserDao userDao = new UserDaoImpl();
Class<?> cls = userDao.getClass();
InvocationHandler handler = new LogInterceptor(userDao);
UserDao proxy = (UserDao) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), handler);
proxy.addUser(new User("tom"));
proxy.deleteUser("tom");
proxy.updateUser("tom");
}
}
测试结果
在工程根目录下生成run.log文件,内容如下:
2015-10-07 05:41:02 Method:addUser start running
2015-10-07 05:41:03 Method:addUser end running
2015-10-07 05:41:03 Method:deleteUser start running
2015-10-07 05:41:05 Method:deleteUser end running
2015-10-07 05:41:05 Method:updateUser start running
2015-10-07 05:41:07 Method:updateUser end running
总结
尽管Java动态代理机制设计的已经非常出色,美中不足之处的是,Java动态代理只能代理实现接口的类。若想要对没有实现任何接口的类进行代理,这种情况确实罕见,需要使用cdlib。Java动态代理机制是实现AOP编程的重要技术之一,动态代理并非开发者日常使用的工具,但是在某些特殊的场景,使用动态代理可以非常好地解决某些类型的问题。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Java性能测试有哪些不为众人所知的原则?Java设计模式??装饰者模式谈谈Java中遍历Map的几种方法Java Web入门必知你需要理解的Java反射机制知识总结编写更好的Java单元测试的7个技巧编程常用的几种时间戳转换(java .net 数据库)适合Java开发者学习的Python入门教程Java webdriver如何获取浏览器新窗口中的元素?Java重写与重载(区别与用途)Java变量的分类与初始化JavaScript有这几种测试分类Java有哪四个核心技术?给 Java开发者的10个大数据工具和框架Java中几个常用设计模式汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南