\@ConfigurationProperties 详解
@ConfigurationProperties 注解详解概述@ConfigurationProperties 是 Spring Framework 提供的一个注解,用于将外部配置(如 YAML 或 properties 文件)绑定到 Java 对象。
它主要用于集中管理应用程序的配置,简化了配置项的读取和使用。
作用
简化配置管理:将多个相关的配置项聚合到一个类中,便于管理和使用。
类型安全:通过强类型的 Java 对象来获取配置,避免了使用字符串常量,减少了出错的可能性。
便于测试:将配置与业务逻辑分离,使得测试变得更加简单。
使用方法添加依赖确保在 pom.xml 中添加 Spring Boot Starter:
1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId></dependency>
创建配置类创建一个类并使用 @Configur ...
为什么Servlet规范规定了只能调用一次getReader方法
为什么一个 Servlet 只能调用一次 getReader() 方法在 Java EE 的 Servlet 规范中,HttpServletRequest 接口的 getReader() 方法用于获取请求体的字符输入流。
然而,一个 Servlet 只能调用一次 getReader() 方法,原因如下:
输入流的单次消费特性
流的性质:输入流(如 BufferedReader)的设计目的是一次性读取数据。读取操作会消耗流中的数据,改变流的状态。调用 getReader() 后,请求体的内容被读取,后续的读取请求会发现流已被关闭或数据已被消费。
设计决策:这种设计确保了输入流的简单性和高效性,避免了复杂的状态管理。它使得开发者在处理请求体时,不必担心流的状态管理和重置。
资源管理
内存和性能:请求体可能很大,尤其在上传文件或大文本数据时。允许多次读取将导致额外的内存开销和性能损失,可能会导致应用程序崩溃或响应缓慢。
避免泄漏:如果允许多个读取,开发者需要显式管理流的生命周期,增加了出错的可能性,如未能正确关闭流,导致内存泄漏。
保持请求的一致性
数据一致性:如果允许多次读取同一请求体 ...
OOD五大原则SOLID总览
OOD五大原则SOLID总览SOLID 是面向对象设计的五大基本原则的首字母缩写,旨在帮助开发者编写更清晰、灵活和易于维护的代码。
它们有助于设计可扩展和可维护的系统,特别是在复杂的项目中应用非常广泛。
详解介绍见链接:
SOLID
LINK
SRP
单一职责原则
OCP
开放封闭原则
LSP
里氏替换原则
ISP
接口隔离原则
DIP
依赖倒置原则
以下是五大 SOLID 原则的简单介绍:
1. 单一职责原则 (Single Responsibility Principle, SRP)定义:每个类应该只有一个职责,即只做一件事。简单来说,一个类应该只有一个引起其变化的原因。
目的:
降低类的复杂度。
提高类的可读性和可维护性。
使代码更容易修改,减少因为一个改动影响到不相关的功能。
示例:12345678910111213141516171819class User { private String name; private String email; // 只处理用户信息 public void updateN ...
接口隔离原则ISP
接口隔离原则 (Interface Segregation Principle, ISP)ISP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义接口隔离原则(Interface Segregation Principle, ISP)规定:客户端不应该被强迫依赖它们不需要的接口。
也就是说,一个接口不应包含过多与客户端无关的方法,而应该根据不同的功能需求,将接口细化为多个具体的接口,以避免冗余和依赖过多不必要的方法。
在设计接口时,ISP 提倡将大而全的接口拆分成多个小而精的接口,每个接口只服务于特定的子功能。
这样,类只会实现自己需要的接口,避免了依赖不必要的接口或方法,从而减少耦合性。
为什么需要接口隔离原则?
减少类与接口的耦合:如果类实现了不相关的方法,会引入不必要的依赖,使代码变得复杂且难以维护。
提高灵活性:细化的接口使类可以根据需要实现相关功能,不受其他不相关功能的影响。
提高系统可维护性:接口更精细、更清晰,使得代码的理解和维护变得更容易。
减少冗余:避免了一个类不得不实现与自己无关的功能,简化了类 ...
开放封闭原则OCP
开放封闭原则 (Open-Closed Principle, OCP)DIP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义开放封闭原则(Open-Closed Principle, OCP)规定:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
也就是说,在不修改现有代码的情况下,通过扩展功能来满足新的需求。
这一原则要求开发者在设计系统时,要确保系统能够适应不断变化的需求,同时尽量避免直接修改已经存在的代码。
通过扩展而非修改来添加新功能,可以减少对现有系统的影响,降低出错的可能性,并提高系统的稳定性和可维护性。
为什么需要开放封闭原则?
减少修改的风险:直接修改已有代码,可能会引发新的错误。开放封闭原则通过扩展功能避免了修改现有代码的风险。
提高代码的灵活性:通过扩展功能,可以轻松地适应需求的变化,而无需触碰核心代码。
支持代码复用:OCP 鼓励通过继承或组合的方式来扩展已有功能,这使得系统中的不同模块能够重复使用现有的代码。
提升代码的可维护性:对修改的封闭意味着代码的稳定性得到了增强,使得维护变 ...
单一职责原则SRP
单一职责原则 (Single Responsibility Principle, SRP)SRP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义单一职责原则(Single Responsibility Principle, SRP)规定:一个类应该只有一个引起其变化的原因。
换句话说,一个类应该只负责一件事情,具有单一职责。
在面向对象设计中,SRP 强调类的职责单一性,以减少类的复杂性和提高其可维护性。
如果一个类承担了多个职责,那么当其中一个职责发生变化时,这个类就需要修改。过多的职责会让类变得臃肿且难以维护,增加代码出错的风险。
原理SRP 背后的逻辑是:任何一个类都应该只负责一项功能,这使得类的结构更加简单且易于理解。
当系统功能发生变化时,只需要修改特定职责的类,而不会影响其他无关功能的代码。
为什么需要单一职责原则?
降低耦合:类的每一项职责都可能与其他系统部分发生交互。职责越多,耦合性越高。
提高可维护性:当某个职责发生变化时,SRP 确保只需要修改相关的类,降低出错的风险。
简化测试:职责单一的类 ...
依赖倒置原则DIP
依赖倒置原则 (Dependency Inversion Principle, DIP)DIP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义依赖倒置原则的核心思想是:高层模块不应该依赖低层模块,二者都应该依赖于抽象。
也就是说,具体的实现类应该依赖于接口或抽象类,而不是高层模块直接依赖实现细节。
依赖倒置原则常常用于创建解耦的系统,减少代码模块之间的直接依赖性。
主要内容
高层模块(如业务逻辑层)不应该依赖低层模块(如数据访问层),二者应该依赖于接口或抽象类。
抽象不应该依赖具体实现,而具体实现应该依赖于抽象。
好处
增强灵活性:代码依赖于接口或抽象类,便于更换不同的实现,而不需要修改高层模块的代码。
解耦模块:高层模块和低层模块通过抽象层进行交互,降低了耦合度,便于维护和扩展。
可扩展性强:添加新的实现类时,不需要改变原有的高层模块,只需实现接口或继承抽象类即可。
示例代码1234567891011121314151617181920212223242526272829303132333435// 抽象层 ...
里氏替换原则LSP
里氏替换原则 (Liskov Substitution Principle, LSP)LSP 是五大 SOLID 原则中的重要组成部分。它们的目标是通过合理的设计和架构,提升系统的可维护性、扩展性和灵活性。
定义里氏替换原则的核心思想是:子类对象必须能够替换其父类对象,并且不会影响程序的正确性。
这意味着子类在扩展父类的功能时,不能改变父类原有的行为。
简单来说,程序中的子类对象应该能在任何父类对象可以出现的地方正常工作。
主要内容
子类应该完全兼容父类,任何使用父类的地方都可以安全地使用子类。
子类在重写父类方法时,不能违反父类的方法行为规范。
子类在继承父类的同时,不应该对父类的功能做破坏性的修改。
好处
增强系统的灵活性:符合 LSP 的子类能够无缝替换父类,使得代码更易于扩展和维护。
提高代码的健壮性:确保子类在继承父类时,不会破坏程序的行为,使得程序更加稳定和可靠。
减少继承带来的副作用:如果子类修改了父类的核心逻辑,可能会带来意料之外的问题。LSP 的遵守可以减少这种副作用。
示例代码123456789101112131415161718192021222324252 ...
Maps.newHashMapWithExpectedSize
Maps.newHashMapWithExpectedSizeMaps.newHashMapWithExpectedSize 是 Guava 库中的一个静态方法
用于创建一个具有预期大小的 HashMap。它通过合理地预估所需的容量,减少 HashMap 在扩容时的开销,从而提升性能。
方法签名1public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize)
参数
expectedSize:预期 HashMap 的大小,也就是你打算存入的键值对数量。此方法会根据这个值来计算合适的初始容量,以尽量减少扩容操作。
关键点:是预期键值对的大小,不是预期容器大小!,实际容量是 expectedSzie ÷ (3/4) 向 2^n 向上取值
返回值
返回一个初始化好的 HashMap<K, V> 对象,其容量已经根据传入的 expectedSize 进行了优化。
重要说明:
容量与负载因子:HashMap 默认的负载因子是 0.75,也就是说,当 ...
ES object与nested
ES object与nested在 ES 中,object 和 nested 是用来表示复杂 JSON 结构的两种字段类型
object 类型object 类型是最基本的嵌套结构,用来表示 JSON 对象中的字段。这些字段会被扁平化存储在同一个文档中。
使用场景
当你需要存储一个简单的对象或键值对,并且不需要在查询时进行复杂的关联操作。
适合处理非数组的嵌套结构,或者数组中的元素之间不需要保持独立的关联。
定义方式123456789101112131415161718PUT /my_index{ "mappings": { "properties": { "user": { "type": "object", "properties": { "first_name": { "type" ...
