教程

Java 21 中对 Emoji 表情支持的改进

1、概览 Java 21 在 java.lang.Character 类中引入了一组新方法,为 Emoji 表情符号提供更好的支持。通过这些方法,我们可以轻松检查某个字符是否是 Emoji 表情符号,并检查 Emoji 表情符号的属性和特征。 本文将带你了解这些新添加的方法,以及与 Java 21 中 Emoji 表情符号处理相关的关键概念。 2、Character API 的更新 Java 21 在 java.lang.Character 类中引入了六个与 Emoji 表情符号处理相关的新方法。所有新方法都是静态的,以代表字符 Unicode 码点的 int 作为参数,并返回 boolean 值。 Unicode 码点是分配给 Unicode 标准中每个字符的唯一数值。它代表不同平台和语言中的特定字符。例如,码点 U+0041 代表字母 A,十六进制形式为 0x0041。 现在,让我们来仔细看看这些与 Emoji 表情符号相关的新方法。 2.1、isEmoji() isEmoji(int codePoint) 方法是新 emoji 方法中最基本的方法。它接收代表字符 Unicode 码点的 int 值,并返回一个 boolean 值,表示该字符是否为 Emoji。 用法如下; String messageWithEmoji = "Hello Java 21! 😄"; String messageWithoutEmoji = "Hello Java!

Spring Boot @MockBean 指南

1、概览 本文将带你了解 Spring Boot @MockBeans 注解的用法。 2、示例项目 以一个简单的票据验证器(Ticket Validator)示例为例: public class TicketValidator { private CustomerRepository customerRepository; private TicketRepository ticketRepository; public boolean validate(Long customerId, String code) { customerRepository.findById(customerId) .orElseThrow(() -> new RuntimeException("Customer not found")); ticketRepository.findByCode(code) .orElseThrow(() -> new RuntimeException("Ticket with given code not found")); return true; } } 如上,我们定义了 validate() 方法,用于检查数据库中是否存在给定数据。它依赖 CustomerRepository 和 TicketRepository。 现在,来看看如何使用 Spring 的 @MockBean 和 @MockBeans 注解创建测试和模拟依赖。 3、@MockBean 注解 Spring 框架提供了 @MockBean 注解,用于模拟依赖以进行测试。该注解允许我们定义特定 Bean 的模拟版本。新创建的模拟 Bean 将被添加到 Spring ApplicationContext 中。因此,如果已经存在相同类型的 Bean,它将被替换为模拟版本。

Spring Boot 配置和绑定二进制数据

Spring Boot 中的 application.yaml / application.properties 配置文件用于定义应用运行时需要的配置属性。 Spring Boot 提供了强大的配置属性绑定功能,可以把配置文件中的属性绑定到 Java Bean,并且会根据 Java Bean 的字段类型对配置属性进行必要的转换。 绑定属性到 Bean 通过一个简单的示例来看看如何把配置文件中的配置属性绑定到 Bean,并且自动转换其类型。 本文使用的 Spring Boot 版本是 3.3.1。 创建 Spring Boot 项目 创建任意 Spring Boot 应用。 定义配置属性 在 src/main/resources 目录下创建 application.yaml 配置文件,并在其中定义如下自定义的配置属性: app: # 数值 port: 8080 # 字符串 title: "Spring Boot 属性绑定测试" # Duration duration: 15s # DataSize data-size: 10MB # 集合 file-types: ["png", "jpeg"] 如上,在配置文件中定义了几个不同类型的配置属性。在本例中,这些配置属性的名称没有任何意义,随意取的。 定义配置 Bean 在 cn.springdoc.demo.prop 包下定义与配置文件中属性相对应的 Bean。 package cn.

Spring AI 集成 Groq - 一个运行速度极快的 AI 推理引擎

更快的信息处理速度不仅能提供信息,还能改变我们的认知和创新方式。 Spring AI 是一个强大的框架,用于将 AI 能力集成到 Spring 应用中,现在已支持 Groq - 一个运行速度极快的 AI 推理引擎,并支持工具/函数调用。 利用 Groq 的 OpenAI 兼容 API,Spring AI 通过调整其现有的 OpenAI Chat 客户端实现了无缝集成。这种方法使开发人员能够通过熟悉的 Spring AI API 利用 Groq 的高性能模型。 本文将带你了解如何配置和使用 Spring AI OpenAI 聊天客户端与 Groq 进行连接。详细信息请查阅 Spring AI Groq 文档 和相关 测试。 Groq API Key 要与 Groq 交互,你需要从 https://console.groq.com/keys 获取 Groq API Key。 依赖 将 Spring AI OpenAI Starter 添加到项目中。 <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> </dependency> 对于 Gradle,在 build.gradle 中添加以下内容:

JPA 异常 “Could Not Determine Recommended JdbcType for Class”

1、简介 本文将带你了解使用 Hibernate 时出现 “could not determine recommended JdbcType for class” 异常的原因,以及解决办法。 2、常见原因 出现该异常,通常是因为 JPA(Java Persistence API)抛出了异常。 这种情况发生在 JPA 无法确定类的推荐 JDBC 类型时。 通常,这会 Hibernate 应用启动期间发生,当 Hibernate 尝试创建数据库 Schema 或验证映射时。 3、复合数据类型 JPA 中出现 “could not determine recommended JdbcType for class” 错误的一个常见原因是,我们在实体类中使用了复合数据类型或其他非原始类型。一个典型的例子就是使用 java.util.Map 来存储动态键值对。 来看看下面这个实体类: @Entity public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // 使用了 Map private Map<String, String> studentDetails; // Getter/Setter 省略 } 在上例中,studentDetails 字段是 Map<String, String>。JPA 可能会抛出错误,因为它无法自动为这种复杂的数据类型确定推荐的 JDBC 类型。

通过 Spring 5 中 Supplier 来获取 Bean

今天遇到了一个面试题:Spring 中 Bean 的实例化有哪些方式? 大家知道,Spring 中 Bean 的配置方式有很多种,但是正常来说,无论你是 XML 文件配置,还是用类似 @Service 注解这种配置,本质上最终都是通过反射去完成 Bean 的初始化的;@Bean 注解则稍微特殊一点,往往我们在 @Bean 注解中是自己 new 出来目标 Bean,但是 @Bean 注解所标记的方法也是通过反射调用的。 似乎 Bean 的实例化离不开反射。 那么除了上面这些方案,还有没有其他方案呢?本文和大家探讨一下这个问题。 以下内容基于 Spring6.0.4。 总所周知,当使用 Spring 容器的时候,如果遇到一些特殊的 Bean,一般来说可以通过如下三种方式进行配置: 静态工厂方法 实例工厂方法 FactoryBean 不过从 Spring5 开始,在 AbstractBeandefinition 类中多了一个属性,对于特殊的 Bean 我们有了更多的选择: /** * Specify a callback for creating an instance of the bean, * as an alternative to a declaratively specified factory method. * <p>If such a callback is set, it will override any other constructor * or factory method metadata.

Lombok 中的 @ExtensionMethod 注解

1、概览 Lombok 是一个流行的 Java 库,它通过减少模板代码来简化代码编写。其强大功能之一是 @ExtensionMethod 注解,可以增强代码的可读性和简洁性。 本文将带你了解 Lombok 中的 @ExtensionMethod 注解有什么用,以及如何有效地使用它。 2、@ExtensionMethod 是什么? @ExtensionMethod 注解允许为现有类添加静态方法扩展。这意味着可以在原始类中调用在其他类中定义的方法。这有利于在不修改源代码的情况下增强第三方库或现有类的功能。 3、@ExtensionMethod 的原理 要使用 @ExtensionMethod,需要用 @ExtensionMethod 来注解一个类,并指定包含想要扩展的静态方法的类。然后,Lombok 会生成必要的代码,使这些方法可用,就好像它们是注解类的方法一样。 假设我们有一个工具类 StringUtils,其中的 reverse() 方法可以反转字符串。我们想把这个方法当作 String 类的一个方法来使用。Lombok 的 @ExtensionMethod 可以帮助我们实现这一目的。 首先,需要在项目中添加 Lombok 依赖。如果使用 Maven,可以在 pom.xml 中添加以下内容: <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> Lombok 的最新版本可以在 Maven 中央仓库 找到。 3.1、String 示例 先创建 StringUtils 工具类,实现 reverse 方法: public static String reverse(String str) { return new StringBuilder(str).reverse().toString(); } 接下来,创建一个使用 @ExtensionMethod 注解的测试类: @ExtensionMethod(StringUtils.class) public class StringUtilsUnitTest { @Test public void givenString_whenUsingExtensionMethod_thenReverseString() { String original = "Lombok Extension Method"; String reversed = original.

使用 @Valid 注解校验嵌套对象

1、简介 本文将带你了解如何使用 @Valid 注解来验证对象及其嵌套的子对象。 当传入数据是基本数据类型,比如 Integer 或 String 时,验证数据可以很简单。然而,当传入信息是一个对象,特别是一个对象图时,验证可能会更加困难。幸运的是,@Valid 注解简化了对嵌套子对象的验证。 2、@Valid 注解是啥 @Valid 注解来自 Jakarta Bean Validation 规范,用于标记需要验证的特定参数。 使用该注解可确保传递给方法或存储在字段中的数据符合指定的验证规则。这有助于提高数据的完整性和一致性。 当在 JavaBean 的字段或方法上使用时,它会触发所有已定义的约束检查。Bean Validation API 中最常用的一些约束包括 @NotNull、@NotBlank、@NotEmpty、@Size、@Email、@Pattern 等。 3、在子对象上使用 @Valid 注解 首先,必须确定验证规则,并对字段应用前面提到的验证约束。 接下来,定义一个 Project 类,该类包含一个嵌套的 User 对象,并用 @Valid 注解来装饰该对象: public class Project { @NotBlank(message = "Project title must be present") @Size(min = 3, max = 20, message = "Project title size not valid") private String title; @Valid // 校验嵌套的对象 private User owner; // 构造函数、Getter、Setter 方法省略 } public class User { // 校验规则 @NotBlank(message = "User name must be present") @Size(min = 3, max = 50, message = "User name size not valid") private String name; // 校验规则 @NotBlank(message = "User email must be present") @Email(message = "User email format is incorrect") private String email; // 构造函数、Getter、Setter 方法省略 } 之后,通过 Validator 实例的 validate() 方法来验证对象:

Spring AI 对 Ollama Tool 的支持

本周早些时候,Ollama 推出 了一项令人兴奋的新功能:对大型语言模型(LLM)的工具支持。 今天,我们非常高兴地宣布 Spring AI(1.0.0-SNAPSHOT)已完全支持这一强大功能,将 Ollama 的函数调用功能引入 Spring 生态系统。 Ollama 的工具支持允许模型决定何时调用外部函数以及如何使用返回的数据。这为访问实时信息到执行复杂计算等各种可能性打开了大门。Spring AI 采用了这一概念,并将其与 Spring 生态系统无缝集成,使 Java 开发人员能够非常轻松地在其应用程序中利用这一功能。Spring AI 的 Ollama 函数调用支持的主要功能包括: 轻松集成:将 Java 函数注册为 Spring Bean,并与 Ollama 模型一起使用。 灵活配置:多种注册和配置函数的方法。 支持多种函数:在一个聊天会话中注册和使用多种函数。 运行时函数选择:动态选择为每个提示(Prompt)启用哪些函数。 代码可移植性:使用不同的 LLM 提供商(如 OpenAI、Mistral、VertexAI、Anthropic、Groq),无需修改代码即可重复使用你的应用代码。 工作原理 定义自定义 Java 函数并将其注册到 Spring AI。 执行可能需要调用函数才能完成回答的聊天请求。 当 AI 模型确定需要调用一个函数时,它会生成一个包含函数名称和参数的 JSON 对象。 Spring AI 会拦截该请求,调用你的 Java 函数,并将结果返回给模型。 该模型将函数的输出纳入其响应中。 入门 先决条件 首先需要在本地计算机上运行 Ollama(0.2.8 以上)。请参阅官方的 Ollama 项目 README,开始在本地计算机上运行模型。然后调出支持模型的工具,例如 Llama 3.1、Mistral、Firefunction v2、Command-R +。。。支持的模型列表可在 模型页面的工具类别 下找到。 ollama pull mistral 依赖 要开始在 Spring AI 中使用 Ollama 函数调用,请在项目中添加以下依赖:

PostConstruct 和 PreDestroy 注解

1、简介 Spring 允许我们在 Bean 的创建和销毁时执行自定义操作。例如,可以让 Bean 实现 InitializingBean 和 DisposableBean 接口,从而在创建和销毁时触发回调方法。 本文将带你了解第二种实现方式,即使用 @PostConstruct 和 @PreDestroy 注解。 2、@PostConstruct Spring 只会在 Bean 属性初始化后调用一次注解了 @PostConstruct 的方法。即使没有任何属性需要初始化,这些方法也会运行。 使用 @PostConstruct 注解的方法可以用任何访问级别,但不能是静态的。 @PostConstruct 一个可能的用途是填充数据。例如,在开发过程中,我们想创建一些默认用户: @Component public class DbInit { @Autowired private UserRepository userRepository; @PostConstruct private void postConstruct() { // 初始化默认用户 User admin = new User("admin", "admin password"); User normalUser = new User("user", "user password"); userRepository.save(admin, normalUser); } } 上述示例将首先初始化 UserRepository 属性,然后运行 @PostConstruct 方法。 3、@PreDestroy 在 Spring 将 Bean 从 Application Context 中删除之前,会运行一次注解了 @PreDestroy 的方法。