Spring的 init-method, @PostConstruct, InitializingBean 对比
Spring的 init-method, @PostConstruct, InitializingBean 对比
在Spring框架中,init-method、@PostConstruct和InitializingBean都是用于定义Bean初始化后执行逻辑的机制,但它们在实现方式、耦合度、执行顺序及适用场景上有所不同。以下是它们的对比总结:
1. InitializingBean 接口
- 机制:实现Spring的
InitializingBean接口,并重写afterPropertiesSet()方法。 - 执行顺序:在依赖注入完成后调用,早于
init-method。 - 优点:直接由Spring管理,逻辑明确。
- 缺点:与Spring框架高度耦合(需实现接口)。
- 适用场景:需要与Spring生命周期紧密集成的场景(但现代Spring应用较少使用)。
public class MyBean implements InitializingBean {@Overridepublic void afterPropertiesSet() {// 初始化逻辑}
}
2. @PostConstruct 注解
- 机制:在方法上添加
@PostConstruct注解(属于JSR-250标准)。 - 执行顺序:在依赖注入后立即执行,早于
InitializingBean和init-method。 - 优点:
- 基于Java标准,与Spring解耦。
- 支持多个方法(按声明顺序执行)。
- 缺点:需要依赖
javax.annotation-api(但Spring Boot默认包含)。 - 适用场景:推荐在大多数场景中使用,符合注解驱动开发的趋势。
public class MyBean {@PostConstructpublic void init() {// 初始化逻辑}
}
3. init-method 配置
- 机制:通过XML或Java配置显式指定初始化方法。
- 执行顺序:最后执行,在
@PostConstruct和afterPropertiesSet()之后。 - 优点:
- 完全解耦,无需修改Bean源码。
- 适用于第三方库或无法修改源码的类。
- 缺点:配置分散,维护成本略高。
- 适用场景:无法修改Bean源码时的初始化配置(如第三方库)。
XML配置示例:
<bean id="myBean" class="com.example.MyBean" init-method="init"/>
Java配置示例:
@Bean(initMethod = "init")
public MyBean myBean() {return new MyBean();
}
对比总结
| 特性 | @PostConstruct | InitializingBean | init-method |
|---|---|---|---|
| 耦合度 | 低(基于JSR标准) | 高(依赖Spring接口) | 无(纯配置) |
| 执行顺序 | 最早 | 中间 | 最晚 |
| 代码侵入性 | 低(仅需注解) | 高(需实现接口) | 无(无需修改Bean代码) |
| 多方法支持 | 是(按声明顺序执行) | 否(仅一个方法) | 否(每个Bean仅一个方法) |
| 适用场景 | 推荐大多数场景 | 遗留代码或特殊需求 | 第三方库或无法修改源码 |
执行顺序
若三者同时存在,执行顺序为:
@PostConstruct注解方法InitializingBean.afterPropertiesSet()init-method指定的方法
选择建议
- 推荐使用
@PostConstruct:符合现代Spring应用风格,解耦且灵活。 - 避免使用
InitializingBean:除非需要与旧代码兼容或明确需要耦合Spring接口。 - 使用
init-method:处理无法修改源码的第三方Bean初始化。
通过合理选择这些机制,可以更优雅地管理Bean的生命周期初始化逻辑。
在Spring框架中,init-method、@PostConstruct和InitializingBean是三种实现Bean初始化逻辑的机制,它们的核心区别在于执行顺序、侵入性和配置方式。以下是详细对比:
1. 执行顺序
三者按以下顺序执行:
@PostConstruct注解方法
(JSR-250标准,由CommonAnnotationBeanPostProcessor处理)InitializingBean.afterPropertiesSet()
(Spring接口,由BeanWrapper调用)init-method配置的方法
(XML或@Bean(initMethod="...")指定,由Bean定义处理)
验证示例:
public class MyBean implements InitializingBean {@PostConstructpublic void postConstruct() { System.out.println("1. @PostConstruct"); }@Overridepublic void afterPropertiesSet() { System.out.println("2. InitializingBean"); }public void customInit() { System.out.println("3. init-method"); }
}// 配置:@Bean(initMethod = "customInit")
输出顺序:1 → 2 → 3
2. 侵入性对比
| 机制 | 侵入性 | 说明 |
|---|---|---|
@PostConstruct | 低 | 仅需添加注解,无需实现特定接口或方法签名。 可以多个 |
InitializingBean | 高 | 必须实现InitializingBean接口并重写afterPropertiesSet()方法。 只能一个 |
init-method | 中 | 需显式配置方法名(XML或注解),但方法本身无需特定签名。 只能一个 |
3. 配置灵活性
@PostConstruct:注解驱动,代码与配置解耦,适合标准化场景。InitializingBean:接口绑定,强制实现,适合需要确保初始化逻辑被Spring管理的场景。init-method:通过配置指定方法名,灵活性最高,适合方法名动态变化或避免代码侵入的场景。
4. 适用场景
@PostConstruct:
推荐作为首选,符合JSR标准,适用于大多数初始化场景(如资源加载、缓存预热)。InitializingBean:
需严格确保初始化逻辑执行时(如依赖注入后必须立即执行),但需注意其侵入性。init-method:
适合需要动态配置初始化方法(如多环境适配),或通过XML集中管理Bean行为。
5. 其他注意事项
- 异常处理:若初始化方法抛出异常,Bean创建会失败,但不会阻止容器启动(除非Bean是关键依赖)。
- 执行条件:所有初始化方法均在Bean属性注入完成后执行。
- 替代方案:Spring Boot中可用
@Bean的initMethod属性,或结合@Lazy延迟初始化。
总结对比表
| 特性 | @PostConstruct | InitializingBean | init-method |
|---|---|---|---|
| 执行顺序 | 1st | 2nd | 3rd |
| 侵入性 | 低(仅注解) | 高(需实现接口) | 中(需配置方法名) |
| 配置方式 | 注解 | 接口实现 | XML/注解配置 |
| 适用场景 | 标准化初始化 | 强制确保初始化执行 | 动态配置初始化方法 |
| Spring版本 | 全版本支持 | 全版本支持 | 全版本支持 |
最佳实践:优先使用@PostConstruct,需强制初始化时用InitializingBean,需动态配置方法名时用init-method。
以下是 init-method、@PostConstruct 和 InitializingBean 的对比分析,从实现方式、执行顺序、依赖关系、灵活性及适用场景等方面展开:
1. 实现方式
| 方法 | 实现方式 |
|---|---|
init-method | 通过 XML 配置或 @Bean 注解的 initMethod 属性指定初始化方法名(如 <bean init-method="init">)。方法需为 public 且无参数。 |
@PostConstruct | 使用 Java 标准注解 @PostConstruct 标记方法,无需额外配置。方法需为 无参数、返回 void,可为任意访问权限(如 private)。 |
InitializingBean | 实现 InitializingBean 接口,必须重写 afterPropertiesSet() 方法。依赖 Spring 特定接口。 |
2. 执行顺序
Spring 的 Bean 初始化流程中,三者的执行顺序为:
InitializingBean.afterPropertiesSet()
(实现InitializingBean接口的方法)@PostConstruct注解方法
(Java 标准注解)init-method配置的方法
(XML 或@Bean注解配置)
执行顺序总结:
afterPropertiesSet() → @PostConstruct → init-method。
3. 依赖关系
| 方法 | 是否依赖 Spring |
|---|---|
init-method | 依赖 Spring 配置(XML 或 @Bean),但方法本身无需 Spring 特定代码。 |
@PostConstruct | 不依赖 Spring,属于 Java 标准注解(javax.annotation.PostConstruct),可在任何支持的容器中使用。 |
InitializingBean | 强依赖 Spring,需实现 Spring 提供的接口 InitializingBean。 |
4. 灵活性
| 方法 | 灵活性 |
|---|---|
init-method | 需在配置中显式指定方法名,灵活性较低,但可针对单个 Bean 自定义方法名。 |
@PostConstruct | 无需配置,直接标注方法,灵活性高,且方法名可任意命名。 |
InitializingBean | 固定方法名 afterPropertiesSet(),无法自定义,灵活性最低。 |
5. 适用场景
| 方法 | 适用场景 |
|---|---|
init-method | - 需要与 XML 配置或 @Bean 注解结合使用时。- 需要自定义初始化方法名(如已有的方法不满足命名规范)。 |
@PostConstruct | - 新项目或注解驱动开发的首选方案。 - 需要与 Java 标准注解兼容,减少对 Spring 的依赖。 |
InitializingBean | - 兼容旧代码或强制要求实现接口的场景。 - 需要与其他 Spring 接口(如 ApplicationContextAware)结合使用。 |
6. 示例代码
init-method
<!-- XML 配置 -->
<bean id="myBean" class="com.example.MyBean" init-method="customInit" />// Java 类
public class MyBean {public void customInit() {System.out.println("init-method executed");}
}
@PostConstruct
// Java 类
public class MyBean {@PostConstructpublic void init() {System.out.println("@PostConstruct executed");}
}
InitializingBean
// Java 类
public class MyBean implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean executed");}
}
7. 总结与推荐
| 方法 | 推荐场景 |
|---|---|
init-method | 需要与 XML 配置结合或需要自定义方法名时使用。 |
@PostConstruct | 首选:简洁、无侵入性,符合 Java 标准,适用于现代 Spring Boot 开发。 |
InitializingBean | 兼容旧代码或必须实现接口时使用,但应优先用 @PostConstruct 替代以减少对 Spring 的依赖。 |
关键注意事项
- 执行顺序:
afterPropertiesSet()→@PostConstruct→init-method。
如果同时使用多个机制,需注意逻辑顺序(例如先初始化依赖项再执行后续操作)。 - 销毁方法对比:
destroy-method对应@PreDestroy,类似init-method与@PostConstruct的关系。
- 避免重复:
不建议同时使用InitializingBean和@PostConstruct,可能会导致逻辑混乱。
希望以上对比能帮助你选择适合的初始化方法!
在 Spring 框架中,init-method、@PostConstruct 和 InitializingBean 都用于在 Bean 实例化之后执行初始化操作,但它们的使用方式、实现机制和应用场景存在差异,下面为你详细对比。
使用方式
1. init - method
这是在 XML 配置或者 Java 配置类里使用 @Bean 注解时指定初始化方法的方式。在 XML 配置文件中,你可以通过 init - method 属性指定 Bean 的初始化方法;在 Java 配置类里,使用 @Bean 注解的 initMethod 属性来指定。
XML 配置示例:
<bean id="exampleBean" class="com.example.ExampleBean" init-method="init"/>
Java 配置示例:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Bean(initMethod = "init")public ExampleBean exampleBean() {return new ExampleBean();}
}class ExampleBean {public void init() {System.out.println("Initializing ExampleBean using init - method");}
}
2. @PostConstruct
这是 JSR - 250 规范定义的注解,需要在 Bean 的方法上添加该注解,此方法就会在 Bean 实例化之后执行。使用该注解需要引入相应的依赖,在 Spring 项目中,一般添加 JSR - 250 的依赖即可。
import javax.annotation.PostConstruct;public class ExampleBean {@PostConstructpublic void init() {System.out.println("Initializing ExampleBean using @PostConstruct");}
}
3. InitializingBean
这是 Spring 提供的一个接口,需要让 Bean 类实现该接口,并重写 afterPropertiesSet() 方法,该方法会在 Bean 的属性设置完成后执行。
import org.springframework.beans.factory.InitializingBean;public class ExampleBean implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("Initializing ExampleBean using InitializingBean");}
}
执行顺序
当一个 Bean 同时使用了这三种方式时,它们的执行顺序为:@PostConstruct > InitializingBean.afterPropertiesSet() > init - method。以下是一个示例:
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.InitializingBean;public class ExampleBean implements InitializingBean {@PostConstructpublic void postConstructInit() {System.out.println("Executing @PostConstruct");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("Executing InitializingBean.afterPropertiesSet()");}public void initMethod() {System.out.println("Executing init - method");}
}
在这个示例中,postConstructInit() 方法会最先执行,接着是 afterPropertiesSet() 方法,最后是 initMethod() 方法。
应用场景
1. init - method
适用于需要在 XML 配置或者 Java 配置类中灵活指定初始化方法的场景。当你希望通过配置文件来控制 Bean 的初始化逻辑,而不是在代码中硬编码时,使用 init - method 是一个不错的选择。
2. @PostConstruct
适用于遵循 JSR - 250 规范的项目,并且希望通过注解的方式来标记初始化方法。该注解具有较好的可移植性,因为它是 JSR - 250 规范的一部分,在其他支持该规范的容器中也可以使用。
3. InitializingBean
适用于需要在代码中明确实现初始化逻辑的场景。当你希望在代码中直接控制初始化过程,并且需要处理可能抛出的异常时,实现 InitializingBean 接口是一个合适的方式。
综上所述,这三种方式各有优缺点,你可以根据具体的项目需求和场景来选择合适的初始化方式。
在 Spring 框架中,init-method、@PostConstruct 和 InitializingBean 都是用来实现 Bean 的初始化逻辑的,但它们的实现方式和适用场景有所不同。以下是它们的详细对比:
1. init-method
- 功能:通过 XML 配置文件或注解
@Bean的init-method属性指定一个初始化方法。 - 实现方式:
- XML 配置:
<bean id="exampleBean" class="com.example.ExampleBean" init-method="init"/> - Java 配置:
@Bean(initMethod = "init") public ExampleBean exampleBean() {return new ExampleBean(); }
- XML 配置:
- 适用场景:
- 适用于 XML 配置或需要显式指定初始化方法的场景。
- 适合简单的初始化逻辑。
- 优点:
- 灵活性高,可以在配置中指定任意方法作为初始化方法。
- 缺点:
- 需要在配置中显式指定方法名,代码和配置分离,可能增加维护成本。
2. @PostConstruct
- 功能:通过注解标记一个方法,该方法会在 Bean 初始化完成后执行。
- 实现方式:
public class ExampleBean {@PostConstructpublic void init() {// 初始化逻辑} } - 适用场景:
- 适用于注解驱动开发。
- 适合需要在代码中直接定义初始化逻辑的场景。
- 优点:
- 代码简洁,注解方式直观。
- 无需额外配置,直接在代码中实现。
- 缺点:
- 依赖于注解,可能不适合某些需要显式配置的场景。
3. InitializingBean
- 功能:通过实现
InitializingBean接口,重写afterPropertiesSet方法来实现初始化逻辑。 - 实现方式:
public class ExampleBean implements InitializingBean {@Overridepublic void afterPropertiesSet() {// 初始化逻辑} } - 适用场景:
- 适用于需要统一管理初始化逻辑的场景。
- 适合需要实现接口的场景(如继承自某个基类)。
- 优点:
- 提供统一的接口,便于统一管理。
- 缺点:
- 引入了接口依赖,可能增加代码的侵入性。
- 如果不需要接口的其他功能,可能会显得冗余。
对比总结
| 特性 | init-method | @PostConstruct | InitializingBean |
|---|---|---|---|
| 实现方式 | XML 或 Java 配置 | 注解 | 实现接口 |
| 灵活性 | 高(可指定任意方法) | 中(注解方式) | 低(需要实现接口) |
| 侵入性 | 低(配置方式) | 中(注解方式) | 高(需要实现接口) |
| 适用场景 | XML 配置或简单初始化 | 注解驱动开发 | 需要统一管理初始化逻辑的场景 |
| 代码与配置分离 | 是(配置与代码分离) | 否(代码中直接定义) | 否(代码中实现接口) |
选择建议
- 如果使用 XML 配置,可以选择
init-method。 - 如果使用注解驱动开发,推荐使用
@PostConstruct。 - 如果需要统一管理初始化逻辑,可以选择
InitializingBean。
在实际开发中,@PostConstruct 是最常用的初始化方式,因为它简单直观且侵入性较低。
1. 核心机制与用法
1.1 init-method
- 定义方式:
在 XML 中通过<bean init-method="...">或在 Java 配置中通过@Bean(initMethod = "...")指定。 - 特点:
- 无侵入性:无需实现接口或添加注解,只需定义一个普通方法。
- 灵活性:可通过配置动态修改初始化方法。
<!-- XML 配置示例 --> <bean id="myBean" class="com.example.MyBean" init-method="customInit"/>
1.2 @PostConstruct
- 定义方式:
在方法上添加@PostConstruct注解。 - 特点:
- 标准化:属于 JSR-250 规范(Java 标准),与 Spring 解耦。
- 简洁性:通过注解直接标记初始化逻辑。
public class MyBean {@PostConstructpublic void init() { /* 初始化逻辑 */ } }
1.3 InitializingBean
- 定义方式:
实现InitializingBean接口并重写afterPropertiesSet()方法。 - 特点:
- 强耦合:直接依赖 Spring 的接口。
- 显式性:方法名明确表达初始化意图。
public class MyBean implements InitializingBean {@Overridepublic void afterPropertiesSet() { /* 初始化逻辑 */ } }
2. 执行顺序
三种初始化方法的调用顺序固定:
@PostConstruct → InitializingBean.afterPropertiesSet() → init-method
- 原因:Spring 生命周期中,注解处理器(如
CommonAnnotationBeanPostProcessor)优先处理@PostConstruct,然后是InitializingBean接口,最后是自定义的init-method。
3. 对比维度
| 维度 | @PostConstruct | InitializingBean | init-method |
|---|---|---|---|
| 耦合性 | 低(JSR-250 标准) | 高(依赖 Spring 接口) | 低(无侵入) |
| 配置方式 | 注解 | 接口实现 | XML 或 Java 配置 |
| 灵活性 | 中(需修改代码) | 低(需修改代码) | 高(配置可动态修改) |
| 适用场景 | 标准化初始化逻辑 | Spring 内部组件或遗留代码 | 解耦且需灵活配置的初始化 |
4. 使用建议
- 优先使用
@PostConstruct:- 符合 Java 标准,与框架解耦,适合大多数场景。
- 慎用
InitializingBean:- 仅用于需要与 Spring 深度集成的组件(如框架内部类)。
- 灵活选择
init-method:- 当需要外部配置初始化方法时使用(例如第三方库的 Bean)。
5. 完整生命周期示例
public class MyBean implements InitializingBean {@PostConstructpublic void postConstruct() {System.out.println("@PostConstruct");}@Overridepublic void afterPropertiesSet() {System.out.println("InitializingBean.afterPropertiesSet()");}public void customInit() {System.out.println("init-method");}
}
输出顺序:
@PostConstruct
InitializingBean.afterPropertiesSet()
init-method
总结
- 解耦需求:优先用
@PostConstruct或init-method。 - 遗留代码:可能需兼容
InitializingBean。 - 控制顺序:理解生命周期顺序,避免逻辑冲突。
Spring 初始化方法对比:init-method、@PostConstruct、InitializingBean
在 Spring 中,Bean 的初始化逻辑可以通过三种方式实现:InitializingBean 接口、@PostConstruct 注解和 init-method 配置。以下是它们的详细对比:
一、核心机制与用法
| 方式 | 机制 | 代码示例 |
|---|---|---|
InitializingBean | Spring 原生接口,实现 afterPropertiesSet() 方法。 | java public class MyBean implements InitializingBean { @Override public void afterPropertiesSet() { /* 初始化逻辑 */ } } |
@PostConstruct | 基于 JSR-250 标准注解,标注初始化方法(需启用注解驱动)。 | java public class MyBean { @PostConstruct public void init() { /* 初始化逻辑 */ } } |
init-method | 通过 XML 或 Java 配置显式指定初始化方法。 | XML: <bean class="com.example.MyBean" init-method="init"/> Java: @Bean(initMethod = "init") |
二、执行顺序与生命周期
-
调用顺序
Spring 容器初始化 Bean 时,三种方法的执行顺序为:
@PostConstruct→InitializingBean.afterPropertiesSet()→init-method
原因:
•@PostConstruct由CommonAnnotationBeanPostProcessor处理,优先级最高。
•InitializingBean是 Spring 原生接口,优先级次之。
•init-method最后执行,确保所有其他初始化逻辑已完成。 -
生命周期阶段
• 依赖注入完成后:所有属性(@Autowired、setter注入等)已设置。
• 初始化阶段:依次调用上述三种初始化方法。
• Bean 就绪:Bean 可被其他组件使用。
三、优缺点对比
| 特性 | InitializingBean | @PostConstruct | init-method |
|---|---|---|---|
| 耦合性 | 高(与 Spring 接口耦合) | 低(基于 JSR-250 标准) | 低(通过配置解耦) |
| 代码侵入性 | 需要实现接口 | 仅需添加注解 | 无侵入(配置指定方法) |
| 灵活性 | 低(仅支持单一方法) | 中(可注解多个方法,但通常只一个有效) | 高(可配置任意方法) |
| 可读性 | 明确接口方法,但需查看实现类 | 注解直观,直接标识初始化逻辑 | 需查看配置确认初始化方法 |
| 多环境兼容性 | 依赖 Spring 环境 | 需 JSR-250 支持(Spring 默认启用) | 通用性强 |
四、使用场景与最佳实践
-
推荐使用
@PostConstruct
• 优势:代码简洁、符合标准、与框架解耦。
• 场景:大多数情况下优先选择,特别是需要代码可移植性的项目。 -
使用
init-method的场景
• 优势:配置灵活,不修改 Bean 代码。
• 场景:第三方库中的类无法修改源码时,通过配置指定初始化方法。 -
避免使用
InitializingBean
• 原因:与 Spring 强耦合,限制了代码的可移植性。
• 替代:优先用@PostConstruct或init-method。
五、异常处理与注意事项
• 异常传播:若初始化方法抛出异常,Spring 会终止 Bean 创建,抛出 BeanCreationException。
• 方法冲突:避免同时使用多种初始化方式(如同时标注 @PostConstruct 并实现 InitializingBean),以免逻辑混乱。
• 销毁方法:对应的销毁阶段可使用 @PreDestroy、DisposableBean 或 destroy-method,其执行顺序与初始化相反。
六、示例代码
// 使用 @PostConstruct
@Component
public class ServiceA {@PostConstructpublic void init() {System.out.println("ServiceA initialized via @PostConstruct");}
}// 使用 InitializingBean
@Component
public class ServiceB implements InitializingBean {@Overridepublic void afterPropertiesSet() {System.out.println("ServiceB initialized via InitializingBean");}
}// 使用 init-method
public class ServiceC {public void customInit() {System.out.println("ServiceC initialized via init-method");}
}// 配置类中指定 init-method
@Configuration
public class AppConfig {@Bean(initMethod = "customInit")public ServiceC serviceC() {return new ServiceC();}
}
输出顺序:
ServiceA initialized via @PostConstruct
ServiceB initialized via InitializingBean
ServiceC initialized via init-method
总结
• @PostConstruct:简洁、标准,适合大多数场景。
• init-method:灵活、解耦,适合配置第三方 Bean。
• InitializingBean:已不推荐使用,除非需要兼容旧代码。
根据项目需求选择合适方式,优先遵循“约定优于配置”原则,保持代码清晰与可维护性。
相关文章:
Spring的 init-method, @PostConstruct, InitializingBean 对比
Spring的 init-method, PostConstruct, InitializingBean 对比 在Spring框架中,init-method、PostConstruct和InitializingBean都是用于定义Bean初始化后执行逻辑的机制,但它们在实现方式、耦合度、执行顺序及适用场景上有所不同。以下是它们的对比总结…...
Gogs 精简备份与恢复方案(仅SQLite数据库和配置)
一、备份方案设计 1. 备份内容 SQLite数据库文件:/home/git/gogs/data/gogs.db 配置和附件:/home/git/gogs/custom 整个目录 2. 备份策略 每周日凌晨2点执行完整备份 保留最近4周的备份文件 备份存储在独立分区 /backup(使用永久化挂载…...
FPGA实现数码管显示分秒时间
目录 一. verilog实现 二. 烧录验证 三. 结果验证 使用开发板:DE2-115开发板 一. verilog实现 要实现分和秒,需要知道定时器的频率,通过查手册可知,我使用的开发板时钟为50hz,也就是时钟一个周期是2微秒。 5000000…...
读书记录九之《在峡江的转弯处-陈行甲人生笔记》
距离上本读完的书,写读后感有很长一段时间了,中间读了几本书,但都没写点文字,没错,是懒病又犯了。陈行甲这本书,一开始从网络上推荐看到,看之前介绍是一本人物自传的回忆录。我个人对这类贴近的…...
可视化开发:用Qt实现Excel级动态柱状图
Qt柱状图 QtChart 首先我们介绍一下 图表建立的基础:Qt Charts QtChart 是Qt框架的一个模块,专注与提供交互式数据可视化功能 俗话就是 用于用户轻松创建各种类型的图表和图形界面 它包含的图表类型有很多:折线图,饼图&#x…...
从零实现Json-Rpc框架】- 项目实现 - 基于Dispatcher模块的RPC框架
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
kubekey -实现懒人一键部署K8S集群
kubekey -实现懒人一键部署K8S集群 操作步骤 官网: https://kubesphere.io/zh/ 一、执行以下命令快速创建一个 Kubernetes 集群。 Master节点 如果您访问 GitHub/Googleapis 受限,请登录 Linux 主机,执行以下命令设置下载区域。 [roottest ~]…...
Android设计模式之模板方法模式
一、定义: 定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 二、结构: AbstractClass抽象类:定义算法的骨架,包含模板方法和若干…...
李宏毅机器学习笔记(1)—机器学习基本概念+深度学习基本概念
机器学习基本概念 1、获取模型 步骤 1.1、假定未知函数 带未知参数的函数 1.2、定义损失函数 真实值:label MAE MSE 几率分布,cross-entropy? 1.3、优化 单独考虑一个参数 让损失函数最小,找导数为零的点 单独考虑w,w…...
数字IC后端项目常见问题之streamOut layermap和innovus drc violation
Q1:我需要将Innovus设计GDS导出到Virtuoso,但发现写出GDS的过程会报如下所示的警告。这里写出GDS使用的是Virtuoso (DFII) streamOut mapping文件! Clock Gen模块Routing DRC,Timing分析及解决 streamOut tease.gds2 -mapFile cd…...
短剧系统开发动漫短剧系统源码开发上线小程序app教程
一、市场规模与用户增长:突破677亿,Z世代成主力 整体扩张 2025年短剧市场预计同比增长15%,规模达677.9亿元,用户规模6.62亿(占网民59.7%)。动漫短剧作为细分领域,增速显著受益于二次元文化渗透&…...
太阳能高杆路灯:照亮未来的新光
在全球能源转型进程加速以及可持续发展理念日益深入人心的背景下,太阳能高杆路灯作为融合新能源技术、智能控制技术与多功能集成特性的创新产品,正逐步革新传统路灯的格局。其不仅有效解决了传统路灯对电网供电的依赖问题,更为城市及乡村的照…...
《C++Linux编程进阶:从0实现muduo 》-第8讲.C++面试如何高效获取线程ID
章节重点 在C面试时,经常被问到如果高效获取线程ID,但不少同学都不知道如何回答。 重点是通过__thread关键字。 重点内容 视频讲解:《CLinux编程进阶:从0实现muduo C网络框架系列》-第8讲. C面试如何高效获取线程ID 测试获取线…...
【Tauri2】011——菜单menu(2)
前言 前面简单地创建了菜单,接下来就来试试菜单中的action Rust中菜单项注册action AppHandle in tauri - Rusthttps://docs.rs/tauri/2.4.0/tauri/struct.AppHandle.html#method.on_menu_event这就需要用到App或者AppHandle中的方法on_menu_event #[must_use] …...
架构设计基础系列:面向对象设计的原则
引言 面向对象设计(Object-Oriented Design,OOD)是软件开发中的重要概念,其核心在于通过对象、类、继承、封装和多态等机制,实现对现实世界问题的抽象和建模。OOD不仅有助于提高代码的可重用性、可维护性和可扩展性&a…...
UE5学习笔记 FPS游戏制作35 使用.csv配置文件
文章目录 导入.csv要求首先创建一个结构体导入配置文件读取配置 导入 .csv要求 第一行必须包含标题 第一列的内容必须不能重复,因为第一列会被当成行的名字,在数据处理中发挥类似于字典的key的作用 当前的配置文件内容如下 首先创建一个结构体 结构…...
嵌入式单片机ADC数模转换的基本方法
第一:模数转换的概述 1:模数转换的概念 一般在电路中,信号分为两种,一种是模拟信号,一种是数字信号,绝大多数传感器采集的都是模拟信号,如温度、湿度、烟雾浓度、亮度.......,但是对于计算机需要处理的数字信号,那就需要利用电路把模拟信号转换为数字信号,这个转换的…...
Web数据挖掘及其在电子商务中的研究与应用
标题:Web数据挖掘及其在电子商务中的研究与应用 内容:1.摘要 随着互联网的飞速发展,Web数据呈现出爆炸式增长,电子商务领域更是积累了海量数据。在此背景下,对Web数据进行有效挖掘并应用于电子商务具有重要意义。本研究旨在探索Web数据挖掘技…...
01-Docker 安装
1、安装环境介绍 安装环境:Linux CentOS 7 本安装教程参考Docker官方文档,地址如下:https://docs.docker.com/engine/install/centos/ 2、卸载旧版docker 首先如果系统中已经存在旧的Docker,则先卸载: yum remove do…...
Redis 的缓存雪崩、击穿、穿透及其解决办法
文章目录 Redis 的缓存雪崩、击穿、穿透及其解决办法缓存雪崩解决办法 缓存击穿解决方案 缓存穿透解决方案 Redis 的缓存雪崩、击穿、穿透及其解决办法 本篇文章回顾 Redis 当中缓存崩溃、击穿、穿透现象以及相应的解决办法,主要的参考资料是:https://w…...
使用 Selenium 构建简单高效的网页爬虫
在当今数据驱动的世界中,网络爬虫已成为获取网络信息的重要工具。本文将介绍如何使用 Python 和 Selenium 构建一个简单而高效的网页爬虫,该爬虫能够处理现代网站的动态内容,支持代理设置和用户配置文件。 为什么选择 Selenium? …...
性能比拼: Pingora vs Nginx (My NEW Favorite Proxy)
本内容是对知名性能评测博主 Anton Putra Pingora vs Nginx Performance Benchmark: My NEW Favorite Proxy! 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 介绍 在本视频中,我们将对比 Nginx 和 Pingora(一个用于构建网络服务的 Rust 框架…...
Ranger一分钟
简介 Ranger Admin:Web UIPolicy Admin Tool:定义和管理策略的模块Ranger Plugins:HDFS、Hive、HBase、Kafka、Storm、YARNRanger UserSync: LDAP、Active DirectoryRanger KMS:管理和保护数据加密的密钥 加密密钥管理…...
STM32单片机入门学习——第5节: [3-1]GPIO输出
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.01 STM32开发板学习——第5节: [3-1]GPIO输出 前言开发板说明引用解答和…...
Open GL ES ->模型矩阵、视图矩阵、投影矩阵等变换矩阵数学推导以及方法接口说明
Open GL ES 变换矩阵详解 一、坐标空间变换流程 局部空间 ->Model Matrix(模型矩阵)-> 世界空间 世界空间->View Matrix(视图矩阵)->观察空间 观察空间 ->Projection Matrix(投影矩阵)->裁剪空间 裁剪空间 ->ViewPort Transform(视口变换)>屏幕空间 …...
AI提示词:自然景区智能客服
提示描述 专为自然景区游客设计的智能客服系统,旨在通过人工智能技术提供实时、准确的景区信息、游览建议、安全提示和服务支持,提升游客的体验质量和满意度。 提示词 # Role: 自然景区智能客服## Profile: - Author: xxx - Version: 1.0 - Language: …...
c#的反射和特性
在 C# 中,反射(Reflection)和特性(Attributes)是两个强大的功能,它们在运行时提供元编程能力,广泛用于框架开发、对象映射和动态行为扩展。以下是对它们的详细介绍,包括定义、用法、…...
智能体项目实现AI对话流式返回效果
1、智能体项目里与AI大模型对话的时候,需要从后端的流式接口里取数据并实现打字机渲染效果。这里涉及到 Markdown 格式的渲染,所以需要配合 marked.js 实现,安装 marked.js : npm install marked 引用: import { ma…...
定时任务(python)
介绍 🧩 什么是“定时任务”? 定时任务,就是按照设定的时间间隔或时间点自动执行某些操作。比如: • 每天早上8点发通知 • 每隔10秒采集一次数据 • 每小时清理一次缓存相关使用 ✅ 最简单的方式:while True tim…...
Python学习第二十七天
yield关键字 yield关键字扮演着核心角色,主要用于处理异步数据流和请求调度。 主要作用 生成器函数:将方法转换为生成器,可以逐步产生结果而不需要一次性返回所有数据 异步处理:支持Scrapy的异步架构,提高爬取效率 …...
