现实生活中的代理想必大家都已经知晓了,下面以买房代理为例讲解!
有三个互相认识的购房者ABC都有购房的需求,但是他们对要购买的房屋都有自己的要求
A:85平
B:90平
C:100平
他们开始活动了,ABC分别在城市中寻找自己的房屋资源
有一天找房都很疲惫的他们都瘫坐在了地上,擦着汗互相分享着自己的找房经历
A想了想就提议可以去找买房代理机构去帮我们找房啊,我们只需要告诉他我们的要求就好了,我们就不用都跑去看房了啊
BC点点头同意了A的观点
于是乎买房代理机构D出现了,并派遣了三个代理进行工作:
代理E>>买房需求:[A:85]
代理F>>买房需求:[B:90]
代理G>>买房需求:[C:100]
<----------------------华丽的分割线------------------------------>
下面我们将上面的故事映射到我们的程序上:
ABC就代表着我们功能中的三个业务类
ABC的买房操作代表着功能中的具体业务逻辑方法
ABC的买房需求(85,90,100)代表着业务逻辑方法的参数
代理D代表着程序中动态代理工厂
EFG代表着动态代理工厂针对三个业务类生成的动态代理对象
<----------------------再来个华丽的分割线------------------------------>
什么是动态代理?
在JDK1.3之后引入了动态代理(Dynamic Proxy)机制,使用该机制,我们可以为指定的接口在系统运行期间动态的生成代理对象
动态代理主要由java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口组成
下面以具体的案例进行分析!
案例背景:
工程内存在转账与库存扣减业务逻辑,需要测试两个业务的耗时
一.案例展示
1.测试准备
项目工程
2.代码展示:
***pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.howie</groupId>
<artifactId>DynamicProxy</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
***InventoryDeduction.java
package com.howie;
/**
* @Author weihuanwen
* @Date 2019/8/20 16:06
* @Version 1.0
*/
public interface InventoryDeduction {
/**
* 业务处理
*/
public void businessProcess();
}
***InventoryDeductionImpl.java
package com.howie.impl;
import com.howie.InventoryDeduction;
/**
* @Author weihuanwen
* @Date 2019/8/20 16:07
* @Version 1.0
*/
public class InventoryDeductionImpl implements InventoryDeduction {
@Override
public void businessProcess() {
try {
//模拟业务处理时间
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
***TransferAccount.java
package com.howie;
/**
* @Author weihuanwen
* @Date 2019/8/20 15:57
* @Version 1.0
*/
public interface TransferAccount {
/**
* 业务处理
*/
public void businessProcess();
}
***TransferAccountImpl.java
package com.howie.impl;
import com.howie.TransferAccount;
/**
* @Author weihuanwen
* @Date 2019/8/20 16:03
* @Version 1.0
*/
public class TransferAccountImpl implements TransferAccount {
@Override
public void businessProcess() {
try {
//模拟业务处理时间
Thread.sleep(11000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
***BusinessProxy.java
package com.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author weihuanwen
* @Date 2019/8/20 16:08
* @Version 1.0
*/
public class BusinessProxy {
/**
* 提供获取业务处理的动态代理对象
* @param consignor 委托者对象
* @return
*/
public Object getBProxy(Object consignor){
/*
参数①:委托者类的类加载器
参数②;委托者类的需求(委托者类实现的接口)
参数③:一个不用关心的接口
*/
Object proxy = Proxy.newProxyInstance(
consignor.getClass().getClassLoader(),
consignor.getClass().getInterfaces(),
new InvocationHandler() {
/**
* 匿名内部类
* 判断委托者对象当前执行的方法
* 使用代理对象执行该方法
* @param proxy 代理对象
* @param method 委托者对象的当前的执行方法
* @param args 方法的参数
* @return 方法的执行结果
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取业务名称
String[] names = consignor.getClass().getName().split("\\.");
String businessName = names[names.length - 1];
System.out.println("代理对象开始执行任务.....");
if (method.getName().equals("businessProcess")) {
long startTime = System.currentTimeMillis();
method.invoke(consignor);
long endTime = System.currentTimeMillis();
System.out.println(businessName+"业务逻辑处理耗时 ::: " + (endTime - startTime)/1000.00 + "s");
}
System.out.println("代理对象结束执行任务.....");
return null;
}
});
System.out.println("获取到动态代理对象.....");
return proxy;
}
}
***MyTest.java
package com.howie;
import com.howie.impl.InventoryDeductionImpl;
import com.howie.impl.TransferAccountImpl;
import com.proxy.BusinessProxy;
import org.junit.Test;
/**
* @Author weihuanwen
* @Date 2019/8/20 16:27
* @Version 1.0
*/
public class MyTest {
@Test
public void testProxy(){
BusinessProxy businessProxy = new BusinessProxy();
System.out.println(">>>开始测试业务耗时");
InventoryDeduction inventoryDeduction =
(InventoryDeduction) businessProxy.getBProxy(new InventoryDeductionImpl());
inventoryDeduction.businessProcess();
System.out.println(">>>测试业务耗时结束");
System.out.println(">>>开始测试业务耗时");
TransferAccount transferAccount =
(TransferAccount) businessProxy.getBProxy(new TransferAccountImpl());
transferAccount.businessProcess();
System.out.println(">>>测试业务耗时结束");
}
}
3.测试
执行测试类中的testProxy()后控制台输出如下:
>>>开始测试业务耗时
获取到动态代理对象.....
代理对象开始执行任务.....
InventoryDeductionImpl业务逻辑处理耗时 ::: 10.0s
代理对象结束执行任务.....
>>>测试业务耗时结束
>>>开始测试业务耗时
获取到动态代理对象.....
代理对象开始执行任务.....
TransferAccountImpl业务逻辑处理耗时 ::: 11.016s
代理对象结束执行任务.....
>>>测试业务耗时结束