做门户网站用什么模板手机h5页面制作软件

张小明 2025/12/30 15:05:53
做门户网站用什么模板,手机h5页面制作软件,如果做微商需不需要开个网站,聊天系统源码一、前言 自从有了AI、大模型、DeepSeek、豆包、GPT......#xff0c;就再也没写过技术文章了。毕竟#xff0c;在它们面前写什么内容都是多余的。我甚至问过AI“AI 时代写技术博客还有意义吗”这个问题#xff0c;它给出了如下结论#xff1a; 结论#xff1a;AI 时代就再也没写过技术文章了。毕竟在它们面前写什么内容都是多余的。我甚至问过AI“AI 时代写技术博客还有意义吗”这个问题它给出了如下结论结论AI 时代技术博客不仅有意义反而变得 更重要 了。 虽然 AI 能快速生成内容但真正的价值恰恰在于人类的独特思考和实践经验 这是 AI 无法完全复制的 极值而 AI 只能产出 平均值。行动建议不要犹豫是否开始而是思考如何将 AI 变成你的创作助手。 本周就选定一个小而精的技术主题尝试 人类构思 AI 辅助 的创作模式体验效率与质量的双重提升。记住在 AI 时代最有价值的不是 写什么而是 你为什么这样写 的独特视角。总感觉它在一本正经的胡说八道但又拿不出来证据偶尔还会被它的“心灵鸡汤”戳中。有时候想想也是AI 是很牛逼但它写不出我深夜改 bug 改到脱发的崩溃AI 是很万能但它写不出一个 bug 是 bug两个 bug 是 feature的玄学代码AI 是能给方案但它给不出在办公室用底层原理驯服测试小姐姐的那种拿捏感。以上便是今天这篇博文的引子字里行间表达了作者对故乡的思念之情对童年时光的怀念之情爱国之情对小日子的痛恨之情等等。二、背景问MyBatis为什么写一个public interface UserMapper接口类就能访问数据库问OpenFeign为什么写一个public interface UserFeignClient接口类就能发送HTTP请求此时你一脸懵逼的说我平常项目就是这么开发的接口会调用xml中我写好的sql接口会调用我注解中的url地址。遗憾的是要是面试时你这么答面试官大概率直接给你打零分 —— 他要的不是 “怎么用”而是 “为什么能这么用”。要搞懂这些问题的核心就绕不开 “动态代理”—— 这正是面试官想考察的底层思维咱们今天就掰烂了揉碎了说说“动态代理的那些事儿”。接下来咱们不背八股直接手搓一个类 OpenFeign 的 “MyHttp”把动态代理扒明白。三、手搓一个“MyHttp”我们要实现的东西暂且叫做“MyHttp”他的目标就是像OpenFeign一样定义一个接口就能发送HTTP请求不需要任何配置和任何实现类。我们首先来看常规调用HTTP接口的代码大概长下面这个样子private static RegisterResponse registerUser(RegisterUserRequest requestParam) throws IOException, ParseException { try (CloseableHttpClient httpClient HttpClients.createDefault()) { //构建POST请求 HttpPost httpPost new HttpPost(http://localhost:8080/api/user/register); //设置请求头 httpPost.setHeader(Content-Type, ContentType.APPLICATION_JSON.toString()); //将请求参数序列化为JSON字符串 String requestJson OBJECT_MAPPER.writeValueAsString(requestParam); HttpEntity requestEntity new StringEntity(requestJson, ContentType.APPLICATION_JSON); httpPost.setEntity(requestEntity); //执行请求获取响应 try (CloseableHttpResponse response httpClient.execute(httpPost)) { //解析响应实体 HttpEntity responseEntity response.getEntity(); if (responseEntity null) { throw new RuntimeException(注册接口返回空响应); } //将响应JSON字符串反序列化为实体类 String responseJson EntityUtils.toString(responseEntity); return OBJECT_MAPPER.readValue(responseJson, RegisterResponse.class); } } }“MyHttp”的目标是这个样子HttpClient(baseUrlhttp://localhost:8080/api) public interface UserHttp { HttpPost(url /user/register) RegisterResponse registerUser(RegisterUserRequest requestParam); }看起来是不是很清爽接下来我们基于动态代理一步一步实现它。四、先搞几个核心注解HttpClient放到接口类上表示这是一个基于“MyHttp”的接口放一个属性baseUrl定义这个接口下的所有HTTP调用的url根路径Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) public interface HttpClient { String baseUrl() default ; }当然如果你愿意还可以扩展其它属性比如你想设置连接超时时间、读超时时间再比如你的baseUrl是动态的或者是个地址列表要负载均衡去调用等等Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) public interface HttpClient { String baseUrl() default ; int connectTimeout() default -1; int readTimeout() default -1;Class? extends BaseUrlSource baseUrlSource() default BaseUrlSource.class; } public interface BaseUrlSource { ListString getBaseUrls(); }HttpPost放在接口方法上表示这个方法具体要调用哪个接口报文头怎么设置超时参数等等Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD}) public interface HttpPost { String url() default ; String contentType() default MediaType.APPLICATION_JSON_VALUE; int connectTimeout() default -1; int readTimeout() default -1; }当然如果你愿意仍然可以扩展很多很多属性但这不是本文重点。五、再实现一下InvocationHandler简单说一下InvocationHandler 是 JDK 动态代理的 “调用处理器”当我们通过Proxy.newProxyInstanceJDK 动态代理的核心方法作用是 “绑定接口和代理逻辑生成最终可用的代理对象”的方式生成对象并调用目标方法时JVM 会自动将调用转发到 InvocationHandler 的 invoke 方法由该方法完成最终的方法执行 自定义增强逻辑。翻译成人话用 InvocationHandler 把 “被代理的接口” 包一层生成一个 “代理对象”之后调用接口方法时其实是在调代理对象的方法自然就会走进 invoke 里咱们写的逻辑。以下例子中我们便在invoke方法中拿到了被代理的接口类和接口方法这时候我们就能拿到所有注解进而根据注解信息组装HTTP报文并发送请求。/** * HTTP动态代理处理器拦截接口方法调用自动发送HTTP请求 */ public class HttpInvocationHandler implements InvocationHandler { // JSON序列化工具全局复用 private static final ObjectMapper OBJECT_MAPPER new ObjectMapper(); // HttpClient客户端 private static final CloseableHttpClient HTTP_CLIENT HttpClients.createDefault(); // 目标接口的Class对象用于解析注解 private final Class? targetInterface; public HttpInvocationHandler(Class? targetInterface) { this.targetInterface targetInterface; } Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 解析接口级HttpClient注解获取基础URL HttpClient httpClientAnnotation targetInterface.getAnnotation(HttpClient.class); String baseUrl httpClientAnnotation.baseUrl(); // 解析方法级HttpPost注解获取子路径 HttpPost httpPostAnnotation method.getAnnotation(HttpPost.class); String subUrl httpPostAnnotation.url(); String contentType httpPostAnnotation.contentType(); // 拼接完整请求URL String fullUrl baseUrl subUrl; //处理请求参数 String requestJson OBJECT_MAPPER.writeValueAsString(args[0]); //发送HTTP POST请求 HttpPost httpPost new HttpPost(fullUrl); // 设置请求头JSON格式 httpPost.setHeader(Content-Type, contentType); // 设置请求体 HttpEntity requestEntity new StringEntity(requestJson); httpPost.setEntity(requestEntity); // 执行请求并获取响应 try (var response HTTP_CLIENT.execute(httpPost)) { HttpEntity responseEntity response.getEntity(); // 解析响应JSON String responseJson EntityUtils.toString(responseEntity); //响应结果反序列化为方法返回类型 Type returnType method.getGenericReturnType(); return OBJECT_MAPPER.readValue(responseJson, OBJECT_MAPPER.constructType(returnType)); } } }六、再写个代理工厂现在我们只差如何创建代理对象了这也是最后一步这时候我们用到了Proxy.newProxyInstance。这个方法你可以想象成被代理对象通过Proxy.newProxyInstance的方式与代理对象绑定了起来这样当被代理对象的方法被调用时实际就变成了代理对象在帮你调用那么就会进入代理对象的invoke方法从而执行我们的增强逻辑。/** * HTTP代理工厂封装动态代理对象的创建逻辑 */ public class HttpProxyFactory { /** * 创建HTTP接口的代理对象 * param interfaceClass 目标接口Class如UserHttp.class * return 接口代理对象 * param T 接口类型 */ public static T T createProxy(ClassT interfaceClass) { // 创建自定义InvocationHandler HttpInvocationHandler handler new HttpInvocationHandler(interfaceClass); // 生成动态代理对象 return (T) Proxy.newProxyInstance( interfaceClass.getClassLoader(), new Class?[]{interfaceClass}, handler ); } }七、核心逻辑串一串进度条走到这里核心逻辑基本梳理完了咱们先简单总结一下整体流程接口注解定义 → 代理工厂创建代理对象 → 调用接口方法触发 invoke → 解析注解组装 HTTP 请求 → 响应反序列化返回。八、测试一下RestController RequestMapping(/demo) public class DemoController { PostMapping(/register) public RegisterResponse register(RequestBody RegisterUserRequest request) { //创建UserHttp接口的代理对象 UserHttp userHttp HttpProxyFactory.createProxy(UserHttp.class); // 调用接口方法底层自动发送HTTP请求 return userHttp.registerUser(request); } }至此上面的实现已经能跑通但总觉得还缺点什么九、还缺点什么有人说你怎么通过UserHttp userHttp HttpProxyFactory.createProxy(UserHttp.class);的方式才能调用我平常项目里都是这样就能调用了Autowired private UserHttp userHttp;这里就涉及到Spring 的 FactoryBean 接口和注解扫描注册器并不是本文重点但还是给大家补全这个 “实战最后一公里”。首先要实现FactoryBean Spring 的 “特殊 Bean 工厂”专门用来创建 “不是简单 new 出来” 的 Bean比如咱们的动态代理对象/** * 自定义FactoryBean生成HTTP接口的动态代理对象 * param T 目标接口类型如UserHttp */ public class HttpProxyFactoryBeanT implements FactoryBeanT { // 目标接口的Class对象 private ClassT interfaceClass; // 构造器注入接口类型 public HttpProxyFactoryBean(ClassT interfaceClass) { this.interfaceClass interfaceClass; } /** * 创建Bean实例返回动态代理对象 */ Override Nullable public T getObject() throws Exception { // 调用之前的动态代理工厂生成代理对象 return HttpProxyFactory.createProxy(interfaceClass); } /** * 返回Bean的类型接口类型 */ Override public Class? getObjectType() { return interfaceClass; } /** * 单例模式代理对象复用 */ Override public boolean isSingleton() { return true; } }然后实现ImportBeanDefinitionRegistrar扫描所有标记了HttpClient的接口自动注册为 Spring Beanpublic class HttpProxyBeanRegistrar implements ImportBeanDefinitionRegistrar { Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //创建扫描器只扫描标记HttpClient的接口 ClassPathScanningCandidateComponentProvider scanner new ClassPathScanningCandidateComponentProvider(false); scanner.addIncludeFilter(new AnnotationTypeFilter(HttpClient.class)); //扫描指定包需替换为实际包名 String basePackage com.demo.http; scanner.findCandidateComponents(basePackage).forEach(beanDefinition - { try { //获取接口的Class对象 String className beanDefinition.getBeanClassName(); Class? interfaceClass ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());//构建BeanDefinition指定Bean类型为HttpProxyFactoryBean BeanDefinitionBuilder builder BeanDefinitionBuilder.genericBeanDefinition(HttpProxyFactoryBean.class); //构造器注入接口Class对象 builder.addConstructorArgValue(interfaceClass); //注册BeanBean名称默认用接口类名首字母小写如userHttp registry.registerBeanDefinition(ClassUtils.getShortNameAsProperty(interfaceClass), builder.getBeanDefinition()); } catch (ClassNotFoundException e) { throw new RuntimeException(扫描HTTP接口失败 e.getMessage(), e); } }); } }最后别忘了关键的一步增加一个配置类导入自定义bean注册器Configuration Import(HttpProxyBeanRegistrar.class) public class HttpProxyAutoConfiguration { }十、再测试一下RestController RequestMapping(/demo) public class DemoController { //自动注入UserHttp接口 Autowired private UserHttp userHttp; PostMapping(/register) public RegisterResponse register(RequestBody RegisterUserRequest request) { // 调用接口方法底层自动发送HTTP请求 return userHttp.registerUser(request); } }这个代码是不是就非常有感觉了。有了这一套面试时被问 “OpenFeign 为什么能直接注入接口用”你不光能说清动态代理还能说清 Spring 是怎么管理这些代理 Bean 的直接碾压八股文选手。十一、结语手搓的意义不止于 “会用”好像没啥可说的了用AI生成一段吧写到这咱们的 “MyHttp” 就彻底跑通了 —— 从注解定义到动态代理拦截再到 Spring 自动注入核心逻辑和 OpenFeign、MyBatis 的接口代理思想完全一致。 可能有人会说“有现成的框架用为啥还要手搓” 答案很简单 面试时“会用” 只能拿及格分“懂原理 能手搓” 才能拿 Offer 工作中遇到框架适配问题时底层原理才是你解决问题的底气。 就像面试官问 “OpenFeign 为什么能直接调用接口”你要是能把今天这一套手搓逻辑讲清楚再对比一下 JDK 动态代理和 CGLIB 的区别 他大概率会觉得 “这小子是真懂不是背八股”。以此表达作者对故乡的思念之情对童年时光的怀念之情爱国之情对小日子的痛恨之情等等。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

筹划电子商务网站建设涿州城乡建设局网站

第一章:Open-AutoGLM唤醒的核心概念Open-AutoGLM 是一种面向自动化任务的开源语言模型框架,专注于理解与生成结构化指令响应。其核心在于“唤醒”机制——即模型能够根据上下文环境、输入模式和元指令动态激活特定功能模块,实现从被动响应到主…

张小明 2025/12/26 12:11:00 网站建设

网贷代理推广网站建设公司十年乐云seo

第一章:cogagent Open-AutoGLM 技术概述cogagent 是基于 Open-AutoGLM 架构构建的智能代理系统,专注于实现自然语言理解与自动化任务执行的深度融合。该技术通过大语言模型(LLM)驱动决策流程,结合外部工具调用能力&…

张小明 2025/12/27 21:59:31 网站建设

佛山微网站建设 天博做网站策划书文档

123云盘免费解锁完整攻略:5分钟开启全功能VIP体验 【免费下载链接】123pan_unlock 基于油猴的123云盘解锁脚本,支持解锁123云盘下载功能 项目地址: https://gitcode.com/gh_mirrors/12/123pan_unlock 还在为123云盘的各种限制而烦恼吗&#xff1f…

张小明 2025/12/27 21:59:19 网站建设

沈阳网页建站模板贵州省中海工程建设有限公司网站

当你面对完全隔离的内网环境,测试工具的部署往往成为技术团队的头号痛点。无法访问外部镜像仓库、依赖下载失败、配置复杂难调试——这些问题是否让你夜不能寐? 【免费下载链接】metersphere MeterSphere 一站式开源持续测试平台,为软件质量保…

张小明 2025/12/27 14:21:53 网站建设

哈尔滨做设计和网站的公司吗外贸推广平台有哪些

MoE架构视频生成终极指南:从技术原理到实战部署 【免费下载链接】Wan2.2-T2V-A14B-Diffusers 项目地址: https://ai.gitcode.com/hf_mirrors/Wan-AI/Wan2.2-T2V-A14B-Diffusers 阿里巴巴达摩院推出的Wan 2.2模型正在重新定义视频生成技术的边界。这款基于混…

张小明 2025/12/27 21:59:13 网站建设

模版网站建设万能转账生成器app

EmotiVoice如何实现语音语调的精细微调控制? 在虚拟主播的一句“我好难过”听起来像在念购物清单,或是智能助手用欢快的语调播报天气预警时,我们便意识到:当前的语音合成技术,缺的不是“说得清”,而是“懂情…

张小明 2025/12/27 15:13:49 网站建设