当前位置: 首页 > news >正文

做网站公司怎么赚钱在线购物网站

做网站公司怎么赚钱,在线购物网站,网店美工具体要求,南昌网站设计单位公司动态代理更改Java方法的返回参数(可用于优化feign调用后R对象的统一处理) 需求原始解决方案优化后方案1.首先创建AfterInterface.java2.创建InvocationHandler处理代理方法3. 调用 实际运行场景拓展 需求 某些场景,调用别人的方法&#xff0…

动态代理更改Java方法的返回参数(可用于优化feign调用后R对象的统一处理)

  • 需求
  • 原始解决方案
  • 优化后方案
    • 1.首先创建AfterInterface.java
    • 2.创建InvocationHandler处理代理方法
    • 3. 调用
  • 实际运行场景
  • 拓展

需求

某些场景,调用别人的方法,但是它外面包了一层,我们只需要里面实际的数据,例如后端开发中的R对象,实际最终只需要data。也就是说可以看成,调用原始方法,代理后更改为别的类型。
下面是R对象,实际运用大同小异,方便大家理解。

public class R<T> implements Serializable {private static final long serialVersionUID = 1L;/*** 正确返回码*/public static final String SUCCESS_CODE = "0";/*** 返回码*/private String code;/*** 返回消息*/private String message;/*** 响应数据*/private T data;/*** 请求ID*/private String requestId;public boolean isSuccess() {return SUCCESS_CODE.equals(code);}
}

下面仅仅举例,重点看出怎么转换返回类型的,没有实际意义。具体使用场景可参考后面可参考具体在实际运用场景的

原始解决方案

PreInterface.java 模拟原始方法返回值。

package com.zdh.proxy.chagemethod;/*** @author zdh* @date 2024/07/24* @desc*/
public interface PreInterface {default double method1() {return 2.3;}default int method2() {return 123;}default boolean method3() {return true;}
}

新建一个PreManager 类,获得PreInterface对象,重新封装所有方法。

package com.zdh.proxy.chagemethod;/*** @author developer_ZhangXinHua* @date 2024/07/24* @desc (详细信息)*/
public class PreManager {//正常从容器中拿PreInterface afterInterface = new PreInterface(){};public String method1() {return "manager: "+ afterInterface.method1();}public String method2() {return "manager: "+ afterInterface.method2();}public String method3() {return "manager: "+ afterInterface.method3();}public static void main(String[] args) {PreManager preManager = new PreManager();System.out.println(preManager.method1());System.out.println(preManager.method2());System.out.println(preManager.method3());}
}

缺点显而易见,每个原始PreInterface就需要对应实现一个PreManager,而且需要重新实现每个方法。

优化后方案

PreInterface.java 与上面一样,不再给出。

1.首先创建AfterInterface.java

重点:因为后面代理的时候需要用到方法名和参数列表进行调用,所以方法名和参数列表一定要与PreInterface的对应的方法名相同。

package com.zdh.proxy.chagemethod;/*** @author zdh* @date 2024/07/24* @desc*/
public interface AfterInterface {public String method1();public String method2();public String method3();
}

2.创建InvocationHandler处理代理方法

package com.zdh.proxy.chagemethod;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** @author zdh* @date 2024/07/24* @desc*/
public class MethodProxyDhHandler implements InvocationHandler {private final Object target;public MethodProxyDhHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//根据反射,拿到和代理后的方法同名且方法参数相同的方法Method targetMethod = target.getClass().getMethod(method.getName(), method.getParameterTypes());Object ob= targetMethod.invoke(target, args);return "proxy after:"+ob;}public static <T> T create(Class<T> interfaceClass, Object target) {return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class[]{interfaceClass},new MethodProxyDhHandler(target));}}

3. 调用

    public static void main(String[] args) {PreInterface preTarget = new PreInterface() {};AfterInterface afterInterface = create(AfterInterface.class, preTarget);String s1 = afterInterface.method1();System.out.println("s1 = " + s1);String s2 = afterInterface.method2();System.out.println("s2 = " + s2);String s3 = afterInterface.method3();System.out.println("s3 = " + s3);}

可以看到,已经全部转成了String类型。这里只是测试,如果使用Spring等框架,可以直接从容器中获取afterInterface ,然后afterInterface 创建代理到容器中。
在这里插入图片描述

实际运行场景

上述方式仅仅为了简化大家的理解,那么现在有个疑问,上述方式有啥用呢。目前我遇到场景可用于优化feign调用后R对象的统一处理 (仅适用公司内部,R对象都统一),获取到R对象,根据错误码等判断成功与否,若成功可以直接拆掉直接返回data。

R.java
后端controller返回参数,大同小异。

package cn.zdh;import lombok.Data;
import lombok.experimental.Accessors;import java.io.Serializable;@Data
@Accessors(chain = true)
public class R<T> implements Serializable {private static final long serialVersionUID = 1L;/*** 正确返回码*/public static final String SUCCESS_CODE = "0";/*** 返回码*/private String code;/*** 返回消息*/private String message;/*** 响应数据*/private T data;/*** 请求ID*/private String requestId;public boolean isSuccess() {return SUCCESS_CODE.equals(code);}/*** 构造带返回数据的成功响应*//*** 构造带返回数据的成功响应*/public static <T> R<T> success(T data) {return new R<T>().setCode(R.SUCCESS_CODE).setData(data);}
}

下面ExampleClientExampleClientImpl 仅用于模拟feign远程调用。正常项目里面只需要一个ExampleClient 接口

package cn.zdh.client;import cn.zdh.R;import java.util.ArrayList;
import java.util.List;/*** @author zdh* @date 2024/07/24* @desc 模拟feign远程调用*/
public interface ExampleClient {default R<String> find1() {return R.success("f1");}default R<List<String>> find2() {List<String> list = new ArrayList<String>();list.add("a");list.add("b");return R.success(list);}default R<Double> find3(Double d) {return R.success(d);}}
package cn.zdh.client;import org.springframework.stereotype.Component;/*** @author developer_ZhangXinHua* @date 2024/07/24* @desc (详细信息)*/
@Component
public class ExampleClientImpl implements ExampleClient{
}

AfterExampleClient 拆掉R之后的data作为方法的返回类型,注意方法名和参数要与ExampleClient 方法名和参数一 一对应。简单来讲,复制粘贴,把返回值删掉R。

package cn.zdh.afterclient;import java.util.List;/*** @author developer_ZhangXinHua* @date 2024/07/23* @desc 定义需要代理后的方法*/
public interface AfterExampleClient {String find1();List<String> find2();Double find3(Double d);
}

ClientProxyDhHandler feign调用其他微服务接口,统一解析代理处理器
可以看到invoke方法中对R对象进行了统一处理,并且后续根据需要,可以通过错误码进行日志输出和报错,通过全局异常处理器,返回前端。

package cn.zdh.proxy;//package com.zdh.proxyfeign;import cn.zdh.R;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*** @author zdh* @date 2024/07/24* @desc  feign调用其他系统接口,统一解析代理处理器*/
public class ClientProxyDhHandler implements InvocationHandler {private final Object target;public ClientProxyDhHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Method targetMethod = target.getClass().getMethod(method.getName(), method.getParameterTypes());R<?> r = (R<?>) targetMethod.invoke(target, args);if (r != null && r.isSuccess()) {return r.getData();}/*后续可以根据错误码进行日志输出和报错,通过全局异常处理器,返回前端。*/return null;}public static <T> T create(Class<T> interfaceClass, Object target) {return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class[]{interfaceClass},new ClientProxyDhHandler(target));}
}

ExampleService 模拟service层的调用

package cn.zdh.service;import cn.zdh.afterclient.AfterExampleClient;
import cn.zdh.client.ExampleClient;
import cn.zdh.proxy.ClientProxyDhHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** @author developer_ZhangXinHua* @date 2024/07/23* @desc  模拟调用代理后的对象。*/
@Service
public class ExampleService{private final AfterExampleClient afterExampleClient;@Autowiredpublic ExampleService(ExampleClient exampleClient) {this.afterExampleClient = ClientProxyDhHandler.create(AfterExampleClient.class, exampleClient);}public void testAll(){//假设这里调用所有String f1 = afterExampleClient.find1();System.out.println("f1 = " + f1);List<String> f2 = afterExampleClient.find2();System.out.println("f2 = " + f2);Double f3 = afterExampleClient.find3(3.2);System.out.println("f3 = " + f3);}}

Spring Test 测试

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@ActiveProfiles(value = "test")
public class ZdhTest {@Autowiredprivate ExampleService exampleService;@Testpublic void test1(){exampleService.testAll();}}

测试结果
在这里插入图片描述
总结,每新增一个Client(feign的微服务调用接口)仅需要创建一个与其对应的AfterClient接口 。需要使用的service,只需要使用动态代理,传入ClientProxyDhHandler并注入到容器中,即可完成统一的远程调用处理。

拓展

如下还有一个小问题,此方式注入到Spring容器中,每次使用者都需要创建代理对象,很麻烦。

@Autowired
public ExampleService(ExampleClient exampleClient) {this.afterExampleClient = ClientProxyDhHandler.create(AfterExampleClient.class, exampleClient);
}

解决方案:通过配置类,一次配置,其他使用者直接进行注入。如下:

@Configuration
public class AfterClientConfiguration {@Beanpublic AfterExampleClient afterExampleClient(ExampleClient exampleClient) {AfterExampleClient afterExampleClient = ClientProxyDhHandler.create(AfterExampleClient.class, exampleClient);return afterExampleClient;}
}

至此,优化完成。🎉🎊

http://www.yayakq.cn/news/56352/

相关文章:

  • 自己建的网站能用吗海东市住房和城乡建设局网站
  • 网站开发人员是做什么的原始传奇网页版
  • 策划书网站项目目标需求分析sem网络推广是什么
  • 网站建设管理界面做一钓鱼网站吗
  • 发布网站的流程网页设计策划案的范文
  • 如何做求婚网站html动态页面代码
  • 汽车制造行业网站模板skxy wordpress
  • 十堰网站建设联系电话h5创建网站
  • 免费制作永久个人网站怎么做全屏网站
  • 黄页网络的推广网站有哪些短视频seo优化排名
  • 做细胞激活的母液网站黄岛建设局网站
  • 电商网站建设与运维需要的软件十堰学校网站建设
  • 怎么开发手机网站wordpress google收录
  • 龙华建网站多少钱网站空间位置是什么
  • 厦门 微网站建设公司哪家好网站制作技术方案
  • 品牌自适应网站建设wordpress时间代码
  • 余杭区网站建设设计公司中国网页设计欣赏
  • 网站设计和网站建设防网站黑客
  • 深圳市住房和建设局网站住房保障服务网站seo在线检测
  • 南阳公司网站制作网站地图 html
  • 九江市做网站的公司把网站做静态化是什么意思
  • 音乐网站建设费用软件开发和网站开发
  • 网站交互图片怎么做的青岛模板建站
  • 温州在线制作网站优秀简历模板
  • 哪个做砍价活动的网站好网站开发php和c语言区别
  • 衡州网站建设seo宝安区住房和建设局网站
  • 烟台高新区建设局网站小网站广告投放
  • 教育云平台网站建设河北网站开发哪家好
  • 正保建设工程教育网站凡科投票
  • 专注徐州网站开发衡水注册公司