静态代理:
每一个需要代理的原始类都需要建一个对应的静态代理类,项目中的类的个数成倍增加,此时就需要动态代理来解决这个问题
动态代理:
- /**
- *
- * 动态代理
- * 如:日志、缓存、监控等场景设计涉及到的框架代码如果不用代理模式,
- * 1、则框架代码与业务代码高度耦合,如果未来需要替换这个框架,那替换的成本比较大
- * 2、框架代码与业务代码无关,本就不应该放到同一个类中,业务类最好职责单一
- * 代理模式的运用场景:
- * 为了将框架代码与业务代码解耦
- * 1.业务系统的非功能性需求开发
- * 2.代理模式在RPC、缓存中的应用 AOP
- *
- * @author jiangwentao
- * @version :MetricsCollectorsProxy.java v1.0 2022/7/25 15:20 jiangwentao Exp $
- */
- public class MetricsCollectorsProxy {
-
- //做监控的框架代码
- private MetricsCollector metricsCollector;
-
- public MetricsCollectorsProxy() {
- this.metricsCollector = new MetricsCollector();
- }
-
- public Object createProxy(Object proxiedObj) {
- Class>[] interfaces = proxiedObj.getClass().getInterfaces();
- DynamicProxyHandler handler = new DynamicProxyHandler(proxiedObj);
- return Proxy.newProxyInstance(proxiedObj.getClass().getClassLoader(), interfaces, handler);
- }
-
- public class DynamicProxyHandler implements InvocationHandler {
-
- private Object proxiedObj;
-
- public DynamicProxyHandler(Object proxiedObj) {
- this.proxiedObj = proxiedObj;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-
- long startTimestamp = System.currentTimeMillis();
- Object result = method.invoke(proxiedObj, args);
- long endTimeStamp = System.currentTimeMillis();
- long responseTime = endTimeStamp - startTimestamp;
- String apiName = proxy.getClass().getName() + ":" + method.getName();
- RequestInfo requestInfo = new RequestInfo(apiName, responseTime, startTimestamp);
- metricsCollector.recordRequest(requestInfo);
- System.out.println("动态代理,记录调用---》");
- return result;
- }
- }
- }