【Java 脚手架】封装通用工具类-1

C# 通俗易懂的介绍基础知识(七)——栈Stack(从日常生活开始讲解) C# 通俗易懂的介绍基础知识(七)——栈Stack(从日常生活开始讲解) 大家好,我是菌菌巧乐兹,励志用最简单的语言来讲解程序知识点。 阅读详情

开此次博客栏目是为了记录我在学习制作 Java 脚手架项目时遇到的问题和知识点,以便后续复盘学习~❄️

Util 类

Util 是工具类,只提供 static 方法,不需要创建对象。如果不手动写构造方法,Java 会自动生成一个无参构造方法,外部就可以创建没有实际用途的对象,故一般在每个 util 类上都会构造一个私有的实例化方法,这样能禁止从外部创建新对象

private JsonUtil() {}

Json

底层用的是 Jackson 的 ObjectMapper,封装了一个通用的 JsonUtil 工具类。序列化没什么问题,writeValueAsString 直接把对象变成 JSON 字符串就行。但反序列化的时候碰到了 Java 泛型擦除的问题,这里记一下当时的场景和解决方式。

泛型擦除

最基本的反序列化方法 string2Obj(String, Class<T>) 只能处理单层对象,比如传入 User.class,Jackson 知道目标是 User,没有歧义。但如果想反序列化成 List<User> 或者 Map<String, User>,因为 JVM 在运行时已经擦除了泛型参数,根本不存在 List<User>.class 这个东西,传给 Jackson 的只有 List.class。Jackson 拿到之后只知道目标是一个 List,但里面的元素该是什么类型,它没有任何信息
所以只能用默认策略,把 JSON 对象映射成 LinkedHashMap,最后拿到的其实是 List<LinkedHashMap>,不是 List<User>,如图所示

Pasted image 20260727175942

这就是泛型擦除造成的。Java 的泛型是编译期做类型检查用的,到了运行期,JVM 不保留泛型的具体类型参数。List<User> 和 List<String> 在运行时对 JVM 来说都只是 List,里面的 <User> 和 <String> 被"擦除"了。这个设计是 Java 5 引入泛型时为了向后兼容做的妥协。像老版本代码里到处都是裸类型的 List、Map,如果泛型在运行时改变了类的结构(像 C# 那样做真泛型),老代码就全部不兼容了。

日常业务代码里通常没影响,因为编译器已经检查过了
但在反序列化场景下,Jackson 需要在运行时知道目标类型的完整泛型信息才能正确映射,这时候泛型擦除就成了问题。

JavaType

对于 List<T> 和 Map<String, T> 这种结构固定、泛型只有一层的场景,可以通过 Jackson 的 TypeFactory 手动构建一个带泛型信息的 JavaType,绕过擦除。

string2List,通过 constructParametricType 告诉 Jackson “我要的是一个 List,里面的元素类型是 clazz”:

public static <T> List<T> string2List(String str, Class<T> clazz) {
    if (!StringUtils.hasLength(str) || clazz == null) return null;
    JavaType javaType = OBJECT_MAPPER.getTypeFactory()
            .constructParametricType(List.class, clazz);
    try {
        return OBJECT_MAPPER.readValue(str, javaType);
    } catch (JsonProcessingException e) {
        log.error("JSON字符串转换为对象列表时发生异常", e);
        return null;
    }
}

此方法在运行时重新把被擦除的类型参数补回去,构造出一个等价于 List<User> 的完整类型描述。

对反序列的 Map 思路完全一样,换成 constructMapType,同时指定 key 和 value 的类型:

public static <T> Map<String,T> string2Map(String str, Class<T> clazz) {
    if (!StringUtils.hasLength(str) || clazz == null) return null;
    JavaType javaType = OBJECT_MAPPER.getTypeFactory()
            .constructMapType(LinkedHashMap.class, String.class, clazz);
    try {
        return OBJECT_MAPPER.readValue(str, javaType);
    } catch (JsonProcessingException e) {
        log.error("JSON字符串转换为对象列表时发生异常", e);
        return null;
    }
}

这里用 LinkedHashMap 而不是 HashMap,是为了可以保持 JSON 中 key 的原始顺序,小巧思

到这里,一层泛型的问题解决了。但如果泛型是嵌套的呢?比如 Map<String, List<User>> 这种两层结构,用 constructParametricType 一层一层手动构建就会变得很繁琐,方法签名也没法通用地表达"任意嵌套深度的泛型"。

嵌套泛型

Jackson 提供了 TypeReference<T> 来解决这个问题。它利用了泛型擦除的一个例外:虽然普通变量的泛型信息在运行时会被擦除,但类定义上的泛型信息会保留在字节码里。当你写 new TypeReference<Map<String, List<User>>>() {} 的时候,实际上是创建了一个匿名内部类继承 TypeReference,这个匿名类在编译时就把 Map<String, List<User>> 这个完整类型写进了字节码的类元数据中。Jackson 在运行时通过反射读取这个类元数据,就能拿到完整的嵌套泛型信息了~

所以封装了一个重载的 string2Obj 方法,接收 TypeReference 参数:

public static <T> T string2Obj(String str, TypeReference<T> typeRef) {
    if (!StringUtils.hasLength(str) || typeRef == null) return null;
    try {
        return OBJECT_MAPPER.readValue(str, typeRef);
    } catch (JsonProcessingException e) {
        log.error("JSON字符串转换为对象时发生异常", e);
        return null;
    }
}

调用的时候,在调用处直接用匿名内部类传入完整的泛型信息。我的测试用例里的场景是 Map<String, List<User>>,developers 和 designers 两组各带一个 User 列表:

String json = "{\"developers\":[{\"name\":\"Julien\",\"age\":18}],"
        + "\"designers\":[{\"name\":\"Luna\",\"age\":20}]}";

Map<String, List<User>> users = JsonUtil.string2Obj(
        json, new TypeReference<Map<String, List<User>>>() {});

assertEquals(List.of(new User("Julien", 18, null)), users.get("developers"));
assertEquals(List.of(new User("Luna", 20, null)), users.get("designers"));

这样无论嵌套多深,TypeReference 都能把完整的类型树带过去,Jackson 就知道最外层是 Map、value 是 List、List 里面是 User

核心思路都是一样的。泛型擦除让运行时丢了类型信息,那就想办法把类型信息补回来,要么通过 JavaType 手动构建,要么通过 TypeReference 利用匿名类的字节码元数据来保留~

Bean 拷贝

从数据库查询出来的对象,和接口最终要返回的对象,通常不是同一个类。比如查询结果是 User,接口返回的是 UserVO,这两个类的字段可能大部分相同。如果每个字段都手动调用 set,代码会比较重复,所以可以手动写一个 copyProperties 方法做必要的属性拷贝。

但是对不同的对象拷贝时会遇到一个问题:方法只知道目标类型是泛型 T,但 Java 不能直接通过泛型创建对象。
方法需要调用方把“如何创建目标对象”传进来,这里就用到了 Supplier<T>:

public static <S, T> List<T> copyListProperties( List<S> sources, Supplier<T> targetSupplier) {

    List<T> targets = new ArrayList<>(sources.size());

    for (S source : sources) {
        T target = targetSupplier.get(); // 获取目标对象
        BeanUtils.copyProperties(source, target);
        targets.add(target);
    }

    return targets;
}

Supplier<T> 的作用是:告诉 Bean 拷贝工具“如何创建一个目标对象”。它是 Java 提供的函数式接口,不接收参数,只通过 get() 返回一个 T 类型的对象。

调用时可以把目标类的构造方法传进去:

List<UserVO> result = copyListProperties( users, UserVO::new);

这里的 UserVO::new 是构造方法引用,等价于:

() -> new UserVO()

也可以直接写成 Lambda:

List<UserVO> result = copyListProperties( users, () -> new UserVO() );

调用这个方法时,编译器会根据参数推断出 S 和 T:S 是源对象类型,T 是目标对象类型。比如传入 List<User> 和 UserVO::new,就相当于完成 User 到 UserVO 的批量拷贝。

这里需要注意,Supplier 每次调用 get() 都应该返回一个新的对象,否则多个源对象可能会被拷贝到同一个目标对象中。另外,BeanUtils.copyProperties 主要适合拷贝同名、类型兼容的属性,嵌套对象通常不会自动进行深层拷贝。

深拷贝与浅拷贝

在 Java 中对象拷贝分为深拷贝和浅拷贝两种方式,它们的核心区别在于对引用类型字段的处理方式不同。

**浅拷贝

浅拷贝只复制对象本身和它的基本类型字段,对于引用类型的字段,只复制引用地址,不复制引用指向的对象。这意味着原对象和拷贝对象会共享同一个引用类型的实例。

public class Address {
    private String city;
    // getter/setter
}

public class User {
    private String name;
    private Integer age;
    private Address address; // 引用类型
    // getter/setter
}

// 浅拷贝示例
User original = new User();
original.setName("Julien");
original.setAge(18);
original.setAddress(new Address("Guangzhou"));

User shallowCopy = new User();
BeanUtils.copyProperties(original, shallowCopy);

// 修改拷贝对象的引用类型字段
shallowCopy.getAddress().setCity("Shenzhen");

// 原对象也受到影响!
System.out.println(original.getAddress().getCity()); // 输出:Shenzhen

常见的浅拷贝方式:

  • Spring 的 BeanUtils.copyProperties()
  • Apache Commons 的 BeanUtils.copyProperties()
  • Object.clone()(需要实现 Cloneable 接口)

**深拷贝

深拷贝会递归复制对象的所有层级,包括引用类型字段指向的对象,创建出完全独立的副本。原对象和拷贝对象完全隔离,互不影响。

User original = new User();
original.setName("Julien");
original.setAge(18);
original.setAddress(new Address("Guangzhou"));

User deepCopy = new User();
deepCopy.setName(original.getName());
deepCopy.setAge(original.getAge());
// 关键:创建新的 Address 对象
Address newAddress = new Address();
newAddress.setCity(original.getAddress().getCity());
deepCopy.setAddress(newAddress);

// 修改拷贝对象的引用类型字段
deepCopy.getAddress().setCity("Shenzhen");

// 原对象不受影响
System.out.println(original.getAddress().getCity()); // 输出:Guangzhou

常见的深拷贝实现方式:

  1. 手动拷贝:为每个引用类型字段创建新对象并赋值(适合层级简单的场景)
  2. 序列化:将对象序列化后再反序列化(对象必须实现 Serializable)
  3. JSON 序列化:通过 JSON 转换实现(性能开销较大,但通用性强)
  4. 第三方库:如 Apache Commons 的 SerializationUtils、Dozer、MapStruct 等

深拷贝工具封装

在脚手架中,可以基于已有的 JsonUtil 封装一个通用的深拷贝工具方法,利用 JSON 序列化和反序列化实现:

/**
 * 深拷贝单个对象
 * 通过 JSON 序列化和反序列化实现完全独立的副本
 */
public static <T> T deepCopy(T source, Class<T> clazz) {
    if (source == null) return null;
    String json = obj2String(source);
    return string2Obj(json, clazz);
}

/**
 * 深拷贝列表
 */
public static <T> List<T> deepCopyList(List<T> sources, Class<T> clazz) {
    if (sources == null || sources.isEmpty()) return new ArrayList<>();
    String json = obj2String(sources);
    return string2List(json, clazz);
}

这种方式的优点是实现简单、通用性强,适合大部分业务场景。缺点是性能开销比手动拷贝大,不适合高频调用。如果对象包含不能被序列化的字段(如 transient、Thread、OutputStream 等),这种方式会丢失这些字段的值。

选择建议

在脚手架项目中如何选择拷贝方式:

  • VO 转换:实体类到视图对象的转换,通常只需要拷贝同名的简单字段,用浅拷贝(BeanUtils.copyProperties)就够了。即使有嵌套对象,只要不修改嵌套对象的内容,浅拷贝也是安全的

  • 缓存隔离:从缓存中取出对象后需要修改,但不能影响缓存中的原对象,这时必须用深拷贝
  • 消息传递:在多线程或消息队列场景中,如果对象会被多个消费者修改,应该用深拷贝确保数据隔离
  • 测试数据:单元测试中需要多次使用同一个初始对象,可以用深拷贝避免测试之间相互影响

性能方面,浅拷贝的开销很小,深拷贝的开销取决于对象的复杂度和实现方式。如果对象层级深、字段多,JSON 序列化的方式会比较慢。对于高频调用的场景,可以考虑用 MapStruct 这种编译期生成代码的工具,或者手动实现拷贝逻辑。

日常开发中,默认用浅拷贝就够了,只有明确需要隔离引用类型字段时才考虑深拷贝

字符串

这次在脚手架里补了一个 StringUtil,需求是判断 URL 是否符合某条规则,以及判断它是否符合规则列表中的任意一条。刚开始可以想到 JDK 自带的 Pattern,但如果规则主要长这样:/api/users/*、/api/**,它其实更像路径匹配,不太适合写成正则。所以这里改用 Spring 的 AntPathMatcher

Pattern

Pattern 属于 JDK 的,规则是完整的正则表达式,适合数字、参数格式、复杂文本等场景:

Pattern.matches("^/api/users/\\d+$", "/api/users/123");

这里的 \\d+ 表示一个或多个数字,^ 和 $ 让规则从字符串开头匹配到结尾。Pattern.matches() 使用的是整段匹配;如果需要在一段文本中寻找局部内容,则要使用 Matcher.find():

Pattern pattern = Pattern.compile("/api/users/\\d+");
Matcher matcher = pattern.matcher("request: /api/users/123");

matcher.find();    // true,找到局部内容
matcher.matches(); // false,整段字符串没有完全符合规则

使用 Pattern 时要注意 Java 字符串本身还会处理一次转义,所以正则里的 \\d 在 Java 字符串中通常要写成 "\\d"。

AntPathMatcher

AntPathMatcher 属于 Spring,参数顺序是“规则在前,实际路径在后”:

AntPathMatcher matcher = new AntPathMatcher();

matcher.match("/api/users/*", "/api/users/123");
matcher.match("/api/**", "/api/users/123/detail");

它的规则主要看路径层级:

  • ?:匹配一个字符。
  • *:匹配当前路径层级中的任意字符,不跨 /。
  • **:匹配零层或多层路径,可以跨 /。

所以 /api/users/* 可以匹配 /api/users/123,但不能匹配 /api/users/123/detail;/api/** 则可以匹配后面多级路径。相比正则,Ant 规则更适合网关白名单、接口路径排除规则和 URL 路径权限判断,规则也更容易读。

区别

  • AntPathMatcher 匹配的是路径规则,不负责判断字符串是不是合法 URL。若需要校验协议、域名和端口,应该先用 URI 解析,再取出 getPath() 进行匹配。直接拿完整 URL 匹配也能工作,但查询参数会成为待匹配字符串的一部分,规则设计时要把这一点考虑进去。
  • Pattern 和 AntPathMatcher 的规则不能混用。/api/** 是 Ant 规则,不是合法的正则;^/api/\\d+$ 是正则,也不能按 Ant 规则理解。项目里选定一种规则后,配置文件、测试用例和工具方法需要保持一致。

如果规则列表很长,还可以考虑提前编译或缓存规则;当前脚手架的规则数量不大,使用 List 的 foreach 逐条判断已经足够,也能保持和单条 URL 匹配方法一致。

还有后续更新…

电商客服效率翻倍!手把手教你用影刀RPA+AI搭建智能回复系统(附实战配置) 本文详细介绍了如何利用影刀RPA+AI技术搭建电商智能客服系统,实现24小时在线回复,大幅提升客服效率。通过零代码配置、Excel词库管理和AI语义理解,系统能处理80%常规咨询,响应速度稳定在3秒内,特别适合中小电商降低成本并提升服务质量。 阅读详情

相关推荐

相机中的归一化实现讲解

本分讲解了图像处理中常出现的两个相机归一化操作

weixin_42102084的博客 1475

脚手架开发-Common封装基础通用工具类<基础工具类>

本文详细介绍了Java微服务脚手架开发中公共模块及基础工具类的封装过程。主要内容包括:1. 创建rs-common公共模块和rs-common-core基础通用包;2. 封装JSON工具类(JsonUtil)实现对象与JSON的相互转换;3. 解决Java泛型擦除问题,实现集合类型的安全转换;4. 封装增强版Bean拷贝工具类(BeanCopyUtil)支持列表拷贝;5. 提供时间戳工具类(TimeStampUtil)和字符串工具类(StringUtil)实现常用功能。文章强调工具类封装应遵循优先使用成熟框

m0_64056556的博客 1150

精确时钟同步协议ptp/IEEE-1588v2协议-------(1)简介

ptp, 1588V2, IEEE-1588, 精确时钟同步协议

meihualing的专栏 5356

【Java 脚手架】封装通用工具类-3

所以引入了本地缓存 [[Caffeine 介绍|Caffeine]],在脚手架里做成了三层缓存结构:L1 是 Caffeine(本地内存),L2 是 Redis,L3 是 DB。因为我会注册很多的 Bean,有给 Redis 的,有 RabbitMQ 的,还有 Caffeine 的,但是都是怎么将合适的 Bean 来装配到对应的 Template 的呢?业务没跑完锁先过期,另一个线程把锁拿走了,原线程 finally 里直接 DEL,删的就是别人的锁。设长了,服务宕机后锁迟迟不释放,后面的请求全堵着;

https://github.com/Jul1en-Lin 225

Cesium实战:从DEM数据到3D地形可视化的全流程解析

本文详细解析了从DEM数据到3D地形可视化的全流程,重点介绍了Cesium和Cesiumlab在数字高程模型(DEM)处理与地形数据转换中的应用。通过实战案例和工具对比,帮助开发者高效实现地形可视化,并分享性能优化与高级功能开发经验。

weixin_29079743的博客 336

深入瑞芯微SDK:手把手解析Uboot、Kernel到Rootfs的镜像生成与烧录

本文深入解析瑞芯微SDK中从Uboot、Kernel到Rootfs的镜像生成与烧录全流程,揭示编译背后的技术细节。通过详细分析SDK架构、镜像生成流水线、分区表定制、Rootfs构建及烧录科学,帮助开发者从会编译进阶到懂原理,掌握系统级开发的关键技术。

weixin_29193359的博客 270

Java脚手架

转载自微信文章:https://mp.weixin.qq.com/s/EZhh9b9iJSdx7F-9MzqmBQ 大家好,我是 Guide 哥,一个三观比主角还正的技术人。 今天推荐几个 Java 项目快速开发脚手架,解放双手 ✋ 从现在开始。 以下推荐项目都是码云上的优质项目,并且都是项目快速开发脚手架,代码质量什么的无法保证能有多好,毕竟很多也是个人开发,或多或少也有个人色彩影响。 不过既然开源出来,这么多人参与,一般情况下项目整体质量可以说是非常不错的了。另外,下面推荐的项目几乎都是码云上面选出来的

newMan1024的博客 4077

MPC-CBF 控制原理详解

假设系统满足如下离散时间动力学模型xt1fxtutxt∈Xut∈Uxt1​fxt​ut​xt​∈Xut​∈Uxtx_txt​:状态变量,定义域为可行状态集X⊆RnX⊆Rnutu_tut​:控制输入,定义域为控制约束集U⊆RmU⊆Rm系统需满足安全约束,由如下控制障碍函数(CBF)hX→RhX→RCx∈X∣hx≥0C:=x∈X∣hx≥。

m0_54691290的博客 1179

前端架构: 脚手架通用框架封装之脚手架注册和命令注册开发(教程二)

接上文,仍旧在 abc-cli 项目中,参考:https://blog.youkuaiyun.com/Tyro_java/article/details/136381086,之前初始化的时候,使用的是 yargs, 现在我们想要使用 commander

Wang的专栏 1416

安装破解IAR EWARM 8.2,提供注册机

IAR Embedded Workbench for ARM(IAR for ARM)是一款微处理器的集成开发环境软件,该集成开发环境中包含了IAR的C/C++编译器、 汇编工具、链接器、库管理器、文本编辑器、工程管理器和C-SPY调试器,支持ARM,AVR,MSP430等芯片。   一、安装 双击运行安装程序,点击Install IAR Embedded Workbench for ARM...

睿思派克 4万+

嵌入式SDIO 总线面试题及参考答案

SDIO 的 4 位总线模式是一种提高数据传输效率的工作模式。在传统的 1 位总线模式下,数据只能通过一根数据线(DAT0)进行传输,这限制了数据传输的带宽和速度。而在 4 位总线模式下,DAT0 - DAT3 这 4 根数据线同时用于数据传输,相当于在同一时间内可以传输 4 倍于 1 位模式的数据量,从而显著提高了数据传输的带宽和速度。要通过 CMD6 命令将 SDIO 总线从当前模式切换到 4 位总线模式,需要遵循以下步骤:第一步,主设备需要确保 SDIO 卡支持 4 位总线模式。

大模型大数据攻城狮的专栏 1719

从0到1快速构建Java项目脚手架

主流的微服务架构体系下,需要按照模块(商品、订单、用户、活动、管理后台……)、按照领域驱动设计等进行拆分成很多的微服务项目,并分配给不同的人负责。如果每个人都一个一个去创建微服务其实是在做重复的工作容易出错而且没有意义,浪费人力物力。如果这个时候基础性的 springboot,springcloud,springcloud-alibaba,MyBatis-Plus, Redis,rocketmq, Hutool, Swagger-UI,SnowFlake-redis等在项目创建时一起生成.

qq_35701988的博客 3947

Vue3 - 实现内网使用天地图离线地图,详解项目加载天地图的离线地图服务器部署与使用教程示例源码,vue3如何实现天地图的离线加载部署在内网访问(天地图资源下载/瓦片等流程教学,实现天地图各种功能)

Vue3中加载天地图的离线地图,天地图——内网使用离线地图,vue3+leaflet实现天地图离线访问,vue3项目中利用leaflet使用天地图,vue3项目中使用天地图离线地图,天地图离线瓦片的打包与发布(GeoServer)天地图离线瓦片数据下载及本地化部署,在内网中无法直接使用外网天地图资源怎么办,在vue3中openLayers加载地图 -使用天地图的瓦片数据。VUE3天地图离线怎么使用,内网部署天地图,天地图离线瓦片,部分瓦片数据,天地图如何离线,无需网络调用天地图API,vue天地图离线地图,

🏆 前端领域优质创作者 1万+

脚手架开发-Common封装<基础工具模块第一部分>

本文介绍了Java微服务脚手架开发中的统一模块封装,主要包括:1. 统一状态码设计,采用6位编码(前3位HTTP状态码+后3位项目细分);2. 统一响应数据结构R<T>封装,包含code、msg、data三要素;3. 全局异常处理方案,通过@RestControllerAdvice+@ExceptionHandler实现微服务层异常捕获,ErrorWebExceptionHandler实现网关层异常处理;4. 自定义ServiceException业务异常模板;5. 参数校验规范,使用sprin

m0_64056556的博客 759

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java项目:Java脚手架项目的通用组件的封装(五)

本文介绍了在Spring Boot项目中封装Redis中间件的实践。

2201_76033461的博客 572

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Kotlin Android 开发脚手架封装

这个脚手架封装了Android开发的核心基础设施,遵循现代Android开发最佳实践,可显著提高开发效率和代码质量。

探索者李小白的博客 583

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

opcj2-盘点几个常见的Java开源脚手架

很多人抱怨自己是CURDer,很多时候就是在简单的修修改改。如果不书序SSM(Spring、SpringMVC和Mybatis)套路的人可能开始的时候会感觉非常吃力。但是熟悉之后发现其实就这么回事。SpringMVC负责响应对外接口,Mybatis负责数据库的访问,Spring则负责整体的bean管理,目前一般都使用SpringBoot做进一步的封装。不管多么复杂的业务,基本结构都是这样子。

纵横千里 捭阖四方 的专栏 2925

脚手架介绍

本文介绍了软件开发中脚手架技术的概念及其应用。在Java开发中,脚手架通过自动化工具生成项目基础结构,类似建筑脚手架,可提高开发效率、统一项目结构并减少错误。文章重点阐述了C++脚手架封装方案,计划整合常用第三方库(如spdlog、gtest、protobuf等)和中间件SDK(如MySQL、Redis、RabbitMQ等),涵盖配置解析、网络通信、日志输出等功能模块。这种封装旨在标准化技术栈、沉淀最佳实践,避免重复开发,提升团队协作效率,体现了工程化思想在不同语言中的实际应用。

Small_entreprene的博客 841

Java项目:Java脚手架项目通用基类和常量类的封装(九)

摘要 本文介绍了Java脚手架项目中通用数据传输类型基类与常量类的封装设计。

2201_76033461的博客 675

Java项目:Java脚手架项目的通用组件的封装(七)

本文介绍了RabbitMQ中间件的封装过程,

2201_76033461的博客 825

什么是编程中的脚手架

脚手架的背景 脚手架这个词在编程领域初次看到是在使用前端框架时。许多团队在制定前端工程方案时会加入脚手架模块。虽然不同的团队对工程化的理解和实施有所差异,但是对于脚手架的定位基本是一致的:创建项目初始文件。这是一条看起来十分简单地准则,但是对于这条准则应该如何理解,如何实施却并不是一件很简单地事情。 在探索这条准则的深度之前,我们不妨看看类似的一些成熟方案,比如Eclipse。这个大名鼎鼎的IDE...

pojpoj的博客 7661

阿里开源android脚手架,Android脚手架搭建

简介脚手架分为MVC\MVP\MVVM三种框架,但是主体结构没有发生明显变化默认首页为LoginActivity默认android:allowBackup="false"项目打开即可使用,如果没有相关依赖,请自行下载目前已实现功能封装状态栏颜色(BaseActivity)加载框封装(BaseActivity中StatusBarCompat.compat(xxx))ButterKnife封装(Bas...

weixin_39942488的博客 1456

如何使用java脚手架调用合约接口

合约进行交互的封装类,提供了部署和加载合约的方法,以及具体操作合约函数的方法。它管理了与合约的交互逻辑,并提供了简化的接口,供应用程序进行与合约的交互和操作。合约的操作和服务,提供了设置和获取合约字符串变量的方法,并负责初始化和管理与合约交互的事务处理器。实例,使得每个实例都可以对应不同的用户地址和交易处理器,方便进行区块链交互操作。中,根据私钥列表的大小,循环遍历私钥列表。中的方法在调用合约接口时的正确性,并检查返回的结果是否符合预期。的多个实例,并根据私钥列表动态创建并配置这些实例。

weixin_63706760的博客 545

Java项目:Java脚手架项目的意义和环境搭建(一)

本文介绍了一个通用脚手架项目的构建过程。项目目的是将常见业务逻辑和基础组件(如网关、统一异常处理等)进行封装,以便后续项目快速开发。

2201_76033461的博客 1591

5个开源的Java项目快速开发脚手架,项目经验有了

今天推荐几个 Java 项目快速开发脚手架,解放双手 ✋ 从现在开始。 以下推荐项目都是码云上的优质项目,并且都是项目快速开发脚手架,代码质量什么的无法保证能有多好,毕竟很多也是个人开发,或多或少也有个人色彩影响。

lujiawei00的专栏 6329

java脚手架系列2--日志、国际化

之所以想写这一系列,是因为之前工作过程中有几次项目是从零开始搭建的,而且项目涉及的内容还不少。在这过程中,遇到了很多棘手的非业务问题,在不断实践过程中慢慢积累出一些基本的实践经验,认为这些与业务无关的基本的实践经验其实可以复刻到其它项目上,在行业内可能称为脚手架,因此决定将此java基础脚手架的搭建总结下来,分享给大家使用。

代码让AI扣 1260
上一篇: 【Claude Code】Compact 源码级别的学习上下文压缩
下一篇: Codex 降智原因与 system prompt 修复指南
Jul1en_
博客等级 码龄2年 275粉丝 75原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值