需求
为老业务系统添加计算接口的执行时间
解决办法
- 第一种解决: 使用模板设计模式来搞定
- 第二种解决: 使用装饰器设计模式来解决(https://blog.csdn.net/qw4339829/article/details/102623006)
- 第三种解决: 动态代理设计模式来搞定
- 第四种解决: 使用Spring AOP
业务代码
//**老业务接口**
public interface MsgService {
String addMsg(String msg);
String updateMsg(String msg);
String delMsg(String msg);
String queryMsg(String msg);
}
//**老业务实现类**
public class MsgServiceImpl implements MsgService {
@Override
public String addMsg(String msg) {
System.out.println("add :" + msg);
return msg;
}
@Override
public String updateMsg(String msg) {
System.out.println("updata :" + msg);
return msg;
}
@Override
public String delMsg(String msg) {
System.out.println("del :" + msg);
return msg;
}
@Override
public String queryMsg(String msg) {
System.out.println("query :" + msg);
return msg;
}
}
动态代理解决
public class ProxyInvocationHandler implements InvocationHandler {
private Object object;
// 传入业务类
public ProxyInvocationHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 生成启动时间
long start = System.currentTimeMillis();
System.out.println(String.format("%s start...", method.getName()));
// 执行业务代码,这里的args是一个对象数组,所以无论你有多少个参数以及参数类型是什么, 都可以使用此来接收
Object response = method.invoke(object, args);
// 生成结束时间
long end = System.currentTimeMillis();
System.out.println(String.format("%s end...", method.getName()));
System.out.println("run time = " + (end - start));
// 返回业务代码执行后的结果
return response;
}
}
public class ProxyService {
public ProxyService() {
//
}
/**
* param service = new MsgServiceImpl() implement MsgService
* return 返回生成的代理类
*/
public static <T> T methodRunTime(Object service){
return (T) Proxy.newProxyInstance(
service.getClass().getClassLoader(),
service.getClass().getInterfaces(),
new ProxyInvocationHandler(service));
}
}
Main
public class App {
public static void main(String[] args) {
// 动态代理模式实现
MsgService msgService = ProxyService.methodRunTime(new MsgServiceImpl());
msgService.addMsg("hahah");
}
}
addMsg start...
add :hahah
addMsg end...
run time = 26
总结
动态代理模式可以帮我们解决,不需要修改代理对象的代码,通过扩展代理类的进行功能的附加和增强。