对于动态代理模式,Java的反射机制提供了支持。
耗时计算写在主逻辑代码存在很强的耦合性,这里提供了一种解耦合的方式去实现,在Spring框架aop也用了这一技术。
登录接口:
public class UserServiceImpl implements IUserService {
public UserServiceImpl() {
}
@Override
public LoginVo login() {
//登录操作
String token = "123";
try {
Thread.sleep(new Random().nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("登录成功!");
return new LoginVo(token);
}
}
利用Proxy.newProxyInstance动态创建实现类
public class PrintUtil {
public static Object createProxy(Object proxiedObject) {
Class<?>[] interfaces = proxiedObject.getClass().getInterfaces();
DynamicProxyHandler handler = new DynamicProxyHandler(proxiedObject);
return Proxy.newProxyInstance(proxiedObject.getClass().getClassLoader(), interfaces, handler);
}
private static class DynamicProxyHandler implements InvocationHandler {
private Object proxiedObject;
public DynamicProxyHandler(Object proxiedObject) {
this.proxiedObject = proxiedObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTimestamp = System.currentTimeMillis();
Object result = method.invoke(proxiedObject, args);
long endTimeStamp = System.currentTimeMillis();
long responseTime = endTimeStamp - startTimestamp;
String apiName = proxiedObject.getClass().getName() + ":" + method.getName();
System.out.println("apiName: " + apiName + "\nneedTime: " + responseTime + " ms");
return result;
}
}
}
上层调用。
public class UserController {
IUserService userService = (IUserService)PrintUtil.createProxy(new UserServiceImpl());
public Object handle(){
return userService.login();
}
}
测试结果:
public class Test {
public static void main(String[] args) {
UserController controller = new UserController();
final Object res = controller.handle();
}
}
登录成功!
apiName: com.cx.learn.model.proxy.UserServiceImpl:login
needTime: 76 ms