Spring的Bean的生命周期 笔记250206

Spring的Bean的生命周期









Spring Bean的生命周期可以分为多个阶段,从Bean的定义加载到最终的销毁,每个阶段都有特定的回调和方法执行。以下是详细的步骤说明:


1. Bean定义加载与解析

  • 配置来源:通过XML、Java注解(如@Component)或Java配置类(@Configuration)定义Bean。
  • BeanDefinition:Spring将每个Bean的配置信息解析为BeanDefinition对象,包含类名、作用域、初始化/销毁方法等元数据。

2. Bean实例化(Instantiation)

  • 实例化方式
    • 构造器实例化:默认通过无参构造器创建对象。
    • 工厂方法:通过静态工厂或实例工厂方法创建。
  • 扩展点
    • InstantiationAwareBeanPostProcessor
      • postProcessBeforeInstantiation():在实例化前拦截,可返回代理对象替代原始Bean。
      • postProcessAfterInstantiation():在实例化后、属性注入前调用,可控制是否继续属性注入。

3. 属性注入(Population of Properties)

  • 依赖注入方式
    • Setter注入:通过<property>标签或@Autowired注解。
    • 字段注入:直接注入字段(需配合@Autowired)。
    • 构造器注入:通过构造器参数注入(推荐方式)。
  • 扩展点
    • AutowiredAnnotationBeanPostProcessor:处理@Autowired@Value注解。
    • CommonAnnotationBeanPostProcessor:处理@Resource@PostConstruct/@PreDestroy

4. Aware接口回调
在属性注入后,Spring会调用一系列Aware接口,向Bean注入容器的基础设施对象:

  • 调用顺序
    1. BeanNameAware:设置Bean的名称。
    2. BeanClassLoaderAware:设置类加载器。
    3. BeanFactoryAware:设置BeanFactory实例。
    4. EnvironmentAware:设置环境变量。
    5. ApplicationContextAware:设置ApplicationContext(需注意:此时Bean还未初始化完成,避免过早访问其他Bean)。

5. BeanPostProcessor前置处理

  • BeanPostProcessor.postProcessBeforeInitialization()
    • 在初始化方法(如@PostConstruct)之前调用。
    • 典型应用:生成代理对象(如AOP)、修改Bean属性。

6. 初始化阶段(Initialization)

  • 执行顺序
    1. @PostConstruct注解方法:JSR-250标准,优先执行。
    2. InitializingBean.afterPropertiesSet():Spring提供的初始化接口。
    3. 自定义初始化方法:通过init-method属性或@Bean(initMethod = "...")指定。
  • 示例
    @Component
    public class MyBean implements InitializingBean {@PostConstructpublic void initAnnotation() { /* ... */ }@Overridepublic void afterPropertiesSet() { /* ... */ }public void customInit() { /* ... */ }
    }
    

7. BeanPostProcessor后置处理

  • BeanPostProcessor.postProcessAfterInitialization()
    • 在初始化完成后调用,可对Bean进行最终修饰。
    • 应用场景:AOP动态代理的生成在此阶段完成。

8. Bean就绪(Ready for Use)

  • 此时Bean已完全初始化,可被其他Bean或应用程序使用。
  • 作用域差异
    • Singleton:容器启动时创建,全局唯一。
    • Prototype:每次请求时创建新实例,容器不管理其销毁。

9. 销毁阶段(Destruction)
当容器关闭(如调用ConfigurableApplicationContext.close())时触发:

  • 执行顺序
    1. @PreDestroy注解方法:JSR-250标准,优先执行。
    2. DisposableBean.destroy():Spring提供的销毁接口。
    3. 自定义销毁方法:通过destroy-method属性或@Bean(destroyMethod = "...")指定。
  • 示例
    @Component
    public class MyBean implements DisposableBean {@PreDestroypublic void preDestroy() { /* ... */ }@Overridepublic void destroy() { /* ... */ }public void customDestroy() { /* ... */ }
    }
    

10. 扩展点总结

扩展接口/注解阶段说明
InstantiationAwareBeanPostProcessor实例化前后可干预Bean创建过程
BeanPostProcessor初始化前后修改或包装Bean
Aware系列接口属性注入后注入容器基础设施对象
@PostConstruct/@PreDestroy初始化/销毁阶段JSR-250标准,优先于Spring接口执行
InitializingBean/DisposableBean初始化/销毁阶段Spring原生接口,执行顺序在注解之后

11. 完整生命周期流程图

1. Bean定义加载↓
2. 实例化(调用构造函数)↓
3. 属性注入(依赖注入)↓
4. Aware接口回调(BeanNameAware、BeanFactoryAware等)↓
5. BeanPostProcessor.postProcessBeforeInitialization()↓
6. 初始化阶段:- @PostConstruct → InitializingBean → init-method↓
7. BeanPostProcessor.postProcessAfterInitialization()↓
8. Bean就绪(使用中)↓
9. 销毁阶段:- @PreDestroy → DisposableBean → destroy-method

12. 注意事项

  • 作用域影响:Prototype作用域的Bean不触发销毁方法,需手动管理。
  • 循环依赖:Singleton作用域的Bean通过三级缓存解决循环依赖,但可能影响生命周期流程。
  • 性能优化:频繁创建/销毁的Bean应优先考虑Prototype作用域,避免Singleton导致内存泄漏。

掌握Bean的生命周期,有助于在复杂场景下精确控制Bean的创建、初始化和销毁过程,是Spring框架深入使用的关键。









Spring的Bean生命周期是指Bean从创建到销毁所经历的一系列过程。了解Bean的生命周期对于开发Spring应用程序至关重要,因为它允许开发者在Bean生命周期的各个阶段插入自定义逻辑,从而实现对Bean行为的灵活定制。以下是Spring Bean生命周期的详细讲解:

一、Bean生命周期概述

Spring Bean的生命周期大致可以分为四个阶段:创建(实例化与依赖注入)、初始化、使用、销毁。每个阶段都包含多个关键步骤,这些步骤共同构成了Bean从创建到消亡的全过程。

二、创建阶段

  1. 元信息配置:通过XML文件、注解或Java代码等方式定义Bean的元信息,如类名、作用域、是否延迟加载等。
  2. 元信息解析:Spring容器启动后,会解析这些元信息,生成BeanDefinition对象,该对象包含了Bean的所有配置信息。
  3. Bean注册:将BeanDefinition注册到Spring容器中,以便后续的管理和使用。
  4. BeanDefinition合并:处理可能存在的BeanDefinition合并情况,确保Bean定义的准确性。
  5. Class加载:加载Bean对应的Class文件。
  6. 实例化:通过反射机制创建Bean的实例。如果是单例Bean,则会在容器启动时立即实例化;如果是多例Bean,则会在每次请求时实例化。在实例化阶段,Spring提供了InstantiationAwareBeanPostProcessor接口,允许开发者在实例化前后插入自定义逻辑。
  7. 属性赋值:为Bean的属性赋值,这包括依赖注入等。Spring容器会根据BeanDefinition中的配置信息,为Bean的属性赋值,并处理属性之间的依赖关系。

三、初始化阶段

  1. Aware接口回调:在属性赋值后、初始化前,Spring会回调Aware接口的方法,为Bean提供对容器的访问能力。例如,BeanNameAware接口允许Bean获取其名称,BeanFactoryAware接口允许Bean获取BeanFactory容器的引用,ApplicationContextAware接口允许Bean获取ApplicationContext上下文。

  2. BeanPostProcessor.postProcessBeforeInitialization:在Bean初始化之前,Spring会调用BeanPostProcessor接口的postProcessBeforeInitialization方法,允许开发者对Bean进行额外的预处理操作,如修改属性、日志记录、添加代理等。

  3. 初始化方法:Spring提供了多种方式让开发者指定Bean的初始化方法。这些方法会在Bean属性赋值完成后被自动调用,用于执行Bean的初始化逻辑。

    • InitializingBean接口:实现了afterPropertiesSet方法的Bean,会在属性赋值后被调用。
    • @PostConstruct注解:带有该注解的方法会在属性赋值后被自动调用。
    • init-method属性:在XML配置或注解中指定的初始化方法,会在属性赋值后被自动调用。
  4. BeanPostProcessor.postProcessAfterInitialization:在Bean初始化方法成功执行之后,Spring会调用BeanPostProcessor接口的postProcessAfterInitialization方法,允许开发者对Bean进行后置处理,如进一步修改Bean的状态、增加额外的功能包装(如代理)等。

四、使用阶段

经过初始化的Bean会被注入到应用程序中,并在需要时被使用。在使用过程中,开发者只需通过依赖注入的方式获取Bean,并调用其方法或操作属性即可。这一阶段的核心是通过Spring提供的IOC(控制反转)机制,让对象的管理与使用解耦,提升代码的灵活性和可测试性。

五、销毁阶段

当Bean不再需要时,Spring容器会对其进行销毁操作。对于单例Bean,这通常发生在容器关闭时;对于多例Bean,则可能发生在请求结束时或Bean被显式销毁时。在销毁阶段,Spring提供了多种方式让开发者指定Bean的销毁方法。这些方法会在Bean销毁时被调用,用于执行资源清理等操作。

  1. DisposableBean接口:实现了destroy方法的Bean,会在销毁时被调用。
  2. @PreDestroy注解:带有该注解的方法会在Bean销毁时被自动调用。
  3. destroy-method属性:在XML配置中指定的销毁方法,会在Bean销毁时被自动调用。

六、注意事项

  1. 避免循环依赖:在Spring中,Bean之间的依赖关系应尽量避免形成循环依赖。虽然Spring提供了三级缓存机制来解决循环依赖问题,但过度依赖这种机制可能会降低系统的可维护性和可读性。
  2. 合理使用作用域:Spring提供了多种作用域(如singleton、prototype、request等),开发者应根据实际情况选择合适的作用域。特别是在使用多例Bean时,需要注意其生命周期和销毁时机。
  3. 利用BeanPostProcessor:BeanPostProcessor是Spring提供的一个强大的扩展点,允许在Bean的初始化前后执行自定义逻辑。开发者可以利用这一特性来实现一些通用的初始化逻辑或检查Bean的状态。

综上所述,Spring的Bean生命周期管理是一个复杂而灵活的过程,它允许开发者在Bean生命周期的各个阶段插入自定义逻辑,从而实现对Bean行为的灵活定制。了解并善用Bean生命周期管理,将有助于开发者更好地利用Spring框架提供的强大功能,开发出高效、可维护的Spring应用程序。









Spring的Bean生命周期是指一个Bean从创建到销毁所经历的一系列过程。理解Bean的生命周期对于开发Spring应用程序至关重要,因为它允许开发者在Bean生命周期的各个阶段插入自定义逻辑,从而实现对Bean行为的精确控制。以下是Spring Bean生命周期的详细讲解:

一、Bean生命周期的主要阶段

Spring Bean的生命周期大致可以分为以下四个阶段:

  1. 实例化(Instantiation)

    • Spring容器根据BeanDefinition中的信息,通过反射机制创建Bean的实例。
    • 如果是单例Bean,容器会在启动时立即实例化;如果是多例Bean,则会在每次请求时实例化。
  2. 属性赋值(Populate Properties)

    • Spring容器将值和Bean的引用注入到Bean对应的属性中。
    • 这包括基本类型的属性、其他Bean的引用等。
  3. 初始化(Initialization)

    • 在属性赋值之后,Spring容器会执行Bean的初始化方法。
    • 初始化方法可能包括实现了特定接口的回调方法(如InitializingBean接口的afterPropertiesSet方法)、自定义的初始化方法(在XML配置或注解中指定)等。
  4. 销毁(Destruction)

    • 当Bean不再需要时,Spring容器会对其进行销毁操作。
    • 销毁方法可能包括实现了DisposableBean接口的destroy方法、使用@PreDestroy注解标记的方法或在Bean配置中指定的销毁方法(destroy-method属性)。

二、Bean生命周期的详细步骤

除了上述主要阶段外,Spring Bean的生命周期还包含以下详细步骤:

  1. Bean定义加载和解析

    • 通过XML文件、注解或Java配置等方式定义Bean的元信息。
    • Spring容器启动后,解析这些元信息并生成BeanDefinition对象。
  2. Bean注册

    • 将BeanDefinition注册到Spring容器中,以便后续的管理和使用。
  3. Bean实例化前处理

    • 在Bean实例化之前,Spring容器会调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法(如果存在)。
  4. Bean实例化

    • 通过反射机制创建Bean的实例。
  5. Bean实例化后处理

    • 在Bean实例化之后,但在属性赋值之前,Spring容器会调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法(如果存在)。
  6. 属性赋值前处理

    • 在属性赋值之前,Spring容器会调用BeanPostProcessor接口的postProcessBeforeInitialization方法(如果存在)。
  7. 属性赋值

    • 为Bean的属性赋值,包括基本类型的属性和其他Bean的引用。
  8. Aware接口回调

    • 如果Bean实现了Aware接口(如BeanNameAwareBeanFactoryAwareApplicationContextAware等),Spring容器会在属性赋值后调用相应的set方法,将相关信息传递给Bean。
  9. 初始化前处理

    • 在初始化方法执行之前,Spring容器会再次调用BeanPostProcessor接口的postProcessBeforeInitialization方法(如果存在,但这一步通常与属性赋值前处理分开考虑,因为它们在逻辑上是独立的)。
  10. 执行初始化方法

    • 执行Bean的初始化方法,包括实现了InitializingBean接口的afterPropertiesSet方法、使用@PostConstruct注解标记的方法或在配置中指定的初始化方法。
  11. 初始化后处理

    • 在初始化方法执行之后,Spring容器会调用BeanPostProcessor接口的postProcessAfterInitialization方法(如果存在)。
  12. Bean就绪

    • 经过初始化的Bean现在已经准备就绪,可以被应用程序中的其他部分使用。
  13. Bean使用

    • 在应用程序中通过依赖注入的方式获取Bean,并调用其方法或操作属性。
  14. 容器关闭和Bean销毁

    • 当Spring容器关闭时,它会销毁所有的单例Bean。
    • 对于多例Bean,销毁时机可能发生在请求结束时或Bean被显式销毁时。
    • 在销毁过程中,Spring容器会调用Bean的销毁方法(如实现了DisposableBean接口的destroy方法、使用@PreDestroy注解标记的方法或在配置中指定的销毁方法)。

三、注意事项

  • 循环依赖:在Spring中,Bean之间的依赖关系应尽量避免形成循环依赖。虽然Spring提供了三级缓存机制来解决循环依赖问题,但过度依赖这种机制可能会降低系统的可维护性和可读性。
  • 作用域选择:Spring提供了多种作用域(如singleton、prototype、request等),开发者应根据实际情况选择合适的作用域。特别是在使用多例Bean时,需要注意其生命周期和销毁时机。
  • BeanPostProcessor的使用BeanPostProcessor是Spring提供的一个强大的扩展点,允许在Bean的初始化前后执行自定义逻辑。开发者可以利用这一特性来实现一些通用的初始化逻辑或检查Bean的状态。

综上所述,Spring的Bean生命周期管理是一个复杂而灵活的过程。了解并善用Bean生命周期管理,将有助于开发者更好地利用Spring框架提供的强大功能,开发出高效、可维护的Spring应用程序。









Spring框架中的Bean生命周期是一个非常重要的概念,它涉及到从创建一个Java对象到成为可被应用程序使用的Spring管理的Bean的整个过程。这个过程包括了多个阶段和扩展点,使得开发者可以在不同的阶段插入自定义逻辑。接下来,我将详细讲解Spring Bean的生命周期,并引用相关资料中的细节。

Bean的生命周期概览

Spring Bean的生命周期大致可以分为四个主要阶段:实例化(Instantiation)、属性赋值(Populate)、初始化(Initialization)以及销毁(Destruction)。每个阶段都有其特定的行为和可能的扩展点。

1. 实例化(Instantiation)

在这一阶段,Spring容器会根据配置元数据(如XML配置或注解)来决定如何创建Bean实例。通常情况下,这涉及使用反射机制调用Bean类的构造函数来创建一个新的实例。如果Bean实现了FactoryBean接口,则可能会通过该接口的方法来创建实例。

此外,在实例化之前和之后,Spring允许通过实现InstantiationAwareBeanPostProcessor接口来添加额外的处理逻辑。例如,可以在实例化前进行一些前置处理,或者在实例化后判断是否需要跳过属性填充步骤。

2. 属性赋值(Populate)

一旦Bean实例被创建出来,接下来就是为这个实例设置属性值的过程。这一步骤包括注入依赖关系,即根据BeanDefinition中指定的依赖关系,将其他Bean注入到当前Bean中。Spring利用依赖注入(DI)机制自动完成这一过程。

同样地,这里也有机会通过InstantiationAwareBeanPostProcessor#postProcessProperties方法对属性赋值过程进行干预,比如修改某些属性的值或完全跳过某些属性的设置。

3. 初始化(Initialization)

初始化是Bean生命周期中最复杂的部分之一,因为它包含了多个子步骤:

  • 检查并应用Aware接口:如果Bean实现了诸如BeanNameAwareBeanFactoryAware等Aware接口,那么相应的回调方法会被调用。
  • 执行BeanPostProcessor前置处理:在这一步,所有注册的BeanPostProcessor都会有机会对Bean进行处理,通常是修改Bean或返回代理对象。
  • 调用InitializingBean接口的afterPropertiesSet方法:如果Bean实现了InitializingBean接口,则会调用afterPropertiesSet()方法。
  • 自定义初始化方法:除了上述方式外,还可以通过配置文件指定一个自定义的初始化方法,无论是通过XML配置还是注解配置都可以做到这一点。

这些步骤确保了Bean在对外提供服务之前已经完成了所有的必要准备工作。

4. 销毁(Destruction)

当容器关闭时,对于单例作用域的Bean,Spring会调用其销毁方法。这可以通过实现DisposableBean接口的destroy()方法来完成,也可以通过配置文件指定一个自定义的销毁方法。对于多例作用域的Bean,Spring不会自动调用销毁方法,因此需要手动管理资源的释放。

扩展点的作用

在整个生命周期过程中,Spring提供了多种扩展点供开发者使用,以增强Bean的功能或控制其行为。这些扩展点包括但不限于:

  • BeanPostProcessor:用于在Bean初始化前后执行自定义逻辑。
  • Aware接口:让Bean能够感知到容器提供的资源,如ApplicationContext
  • FactoryBean:用于定制化Bean的创建过程。

结论

理解Spring Bean的生命周期不仅有助于更好地掌握Spring的核心功能,还能帮助我们更高效地开发和维护基于Spring的应用程序。通过合理利用生命周期中的各个扩展点,我们可以更加灵活地控制Bean的行为,满足复杂业务需求。总之,深入学习和理解Spring Bean的生命周期是每一位Spring开发者成长道路上不可或缺的一部分。

请注意,由于篇幅限制,这里的解释简化了许多细节。实际的Spring Bean生命周期比这里描述的要复杂得多,特别是当你开始深入了解Spring源码时,你会发现还有更多的钩子和回调可供利用。









Spring中Bean的生命周期是指从Bean的创建、初始化到销毁的整个过程,以下是对其详细的讲解:

Bean的定义与实例化

  • 配置与扫描:在Spring配置文件(如XML配置或通过注解配置)中定义Bean,Spring容器启动时会根据配置信息进行Bean的扫描,识别需要创建的Bean。例如,使用@Component注解标记的类,会被Spring的组件扫描机制识别为Bean。
  • 实例化:Spring容器根据Bean的定义创建Bean实例,实例化方式有多种,如通过构造函数实例化、通过工厂方法实例化等。若一个Bean有多个构造函数,Spring会根据依赖关系和配置选择合适的构造函数进行实例化。

依赖注入

  • 属性注入:通过@Autowired@Resource等注解或XML配置中的<property>标签,Spring将其他Bean或依赖对象注入到当前Bean的属性中。比如一个Service层的Bean依赖于Dao层的Bean,就可以通过属性注入将Dao层Bean注入到Service层Bean中。
  • 构造函数注入:在Bean的构造函数中声明所需的依赖,Spring会在实例化Bean时将相应的依赖对象作为参数传入构造函数。例如,一个UserService类的构造函数接受一个UserDao类型的参数,Spring会在创建UserService实例时将UserDao的实例传入。

初始化前处理

  • BeanPostProcessor前置处理:在Bean初始化之前,BeanPostProcessorpostProcessBeforeInitialization方法会被调用,允许开发者对Bean进行一些前置处理,如修改Bean的属性等。可以实现BeanPostProcessor接口并将其注册到Spring容器中,对所有Bean或特定类型的Bean进行统一的前置处理逻辑。

初始化

  • 实现InitializingBean接口:如果Bean实现了InitializingBean接口,其afterPropertiesSet方法会在依赖注入完成后被调用,用于执行一些初始化操作,如资源的初始化、数据的加载等。
  • 使用@PostConstruct注解:在方法上使用@PostConstruct注解,该方法会在Bean的依赖注入完成后被自动调用,同样用于执行初始化逻辑。
  • 自定义init-method:在XML配置中可以通过init-method属性指定一个方法作为初始化方法,或者在基于Java配置的方式中,使用@Bean(initMethod = "initMethodName")来指定初始化方法。

初始化后处理

  • BeanPostProcessor后置处理:在Bean初始化之后,BeanPostProcessorpostProcessAfterInitialization方法会被调用,开发者可以在此对初始化后的Bean进行进一步的处理,如代理增强等。Spring AOP中的动态代理生成就是在这个阶段进行的,通过BeanPostProcessor对目标Bean创建代理对象。

Bean的使用

  • 应用中的调用:在Spring容器管理下,Bean可以被其他组件或Bean进行调用和使用,提供相应的业务功能。在Web应用中,Controller层可以调用Service层的Bean来处理业务逻辑,Service层又可以调用Dao层的Bean来进行数据访问操作。

销毁前处理

  • 实现DisposableBean接口:如果Bean实现了DisposableBean接口,在Spring容器关闭时,其destroy方法会被调用,用于释放资源、关闭连接等清理操作。
  • 使用@PreDestroy注解:在方法上使用@PreDestroy注解,当Spring容器准备销毁Bean时,会调用标注了该注解的方法,进行资源清理等工作。
  • 自定义destroy-method:在XML配置中可以通过destroy-method属性指定一个方法作为销毁方法,或者在基于Java配置的方式中,使用@Bean(destroyMethod = "destroyMethodName")来指定销毁方法。

销毁

  • Bean的清理:Spring容器在关闭时会遍历所有管理的Bean,按照一定的顺序调用它们的销毁方法,完成资源的释放和清理工作,确保应用程序能够正常结束,避免资源泄露等问题。

在整个生命周期中,Spring还提供了一些其他的扩展点和机制,如BeanFactoryPostProcessor可以在BeanFactory创建后、Bean实例化前对Bean的定义进行修改等,这些都为开发者提供了丰富的手段来定制和扩展Bean的生命周期行为。









Spring Bean的生命周期主要包括以下几个阶段:

1. 实例化

  • 描述:Spring容器根据Bean定义创建Bean实例。
  • 步骤
    1. Spring容器读取配置文件或注解信息,确定需要创建的Bean。
    2. 使用反射机制调用Bean的构造函数,创建Bean实例。

2. 属性赋值

  • 描述:Spring容器将Bean定义中的属性值注入到Bean实例中。
  • 步骤
    1. Spring容器解析Bean定义中的属性信息。
    2. 通过setter方法或直接赋值的方式,将属性值注入到Bean实例中。

3. 初始化

  • 描述:Bean实例在初始化阶段会执行一些特定的操作,如调用初始化方法、应用Aware接口等。
  • 步骤
    1. Aware接口回调:如果Bean实现了Aware接口(如BeanNameAware、BeanFactoryAware等),Spring容器会调用相应的回调方法,使Bean能够获取到Spring容器的引用或其他信息。
    2. BeanPostProcessor前置处理:如果配置了BeanPostProcessor,Spring容器会调用其postProcessBeforeInitialization方法,允许对Bean进行自定义处理。
    3. InitializingBean接口回调:如果Bean实现了InitializingBean接口,Spring容器会调用其afterPropertiesSet方法,进行Bean的初始化操作。
    4. 自定义初始化方法:如果Bean定义中指定了初始化方法(如init-method),Spring容器会调用该方法。
    5. BeanPostProcessor后置处理:Spring容器会调用BeanPostProcessor的postProcessAfterInitialization方法,允许对Bean进行进一步的自定义处理。

4. 使用

  • 描述:Bean实例化、初始化完成后,可以被应用程序使用。

5. 销毁

  • 描述:当Spring容器关闭时,会销毁所有的单例Bean。
  • 步骤
    1. DisposableBean接口回调:如果Bean实现了DisposableBean接口,Spring容器会调用其destroy方法,进行Bean的销毁操作。
    2. 自定义销毁方法:如果Bean定义中指定了销毁方法(如destroy-method),Spring容器会调用该方法。

代码示例
以下是一个简单的Spring Bean生命周期示例:

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;@Component
@Scope("singleton")
public class MyBean implements InitializingBean, DisposableBean {@Autowiredprivate MyDependency myDependency;public MyBean() {System.out.println("1. 实例化");}public void setMyDependency(MyDependency myDependency) {this.myDependency = myDependency;System.out.println("2. 属性赋值");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("3. InitializingBean接口回调");}public void initMethod() {System.out.println("3. 自定义初始化方法");}@Overridepublic void destroy() throws Exception {System.out.println("5. DisposableBean接口回调");}public void customDestroyMethod() {System.out.println("5. 自定义销毁方法");}
}

配置文件

<bean id="myBean" class="com.example.MyBean" init-method="initMethod" destroy-method="customDestroyMethod"><property name="myDependency" ref="myDependency"/>
</bean>
<bean id="myDependency" class="com.example.MyDependency"/>

通过上述示例,可以看到Spring Bean的生命周期各个阶段的执行顺序和具体操作。
















Springboot有哪些Aware接口?其执行顺序是怎样的?

在 Spring Boot 中,所有的 Aware 接口均继承自 Spring Framework,因为 Spring Boot 是基于 Spring Framework 的封装。这些接口在 Bean 的生命周期中按特定顺序触发,帮助 Bean 感知容器环境或基础设施。以下是 Spring Boot 中常见的 Aware 接口及其执行顺序的详细说明:


1. Spring Boot 中常见的 Aware 接口

Aware 接口作用
BeanNameAware获取 Bean 的名称(idname)。
BeanClassLoaderAware获取加载当前 Bean 的类加载器。
BeanFactoryAware获取 BeanFactory 实例,用于直接访问容器的基础功能(如获取其他 Bean)。
EnvironmentAware获取 Environment 对象,访问环境变量和配置文件属性。
EmbeddedValueResolverAware获取 StringValueResolver,用于解析 ${} 占位符和 SpEL 表达式。
ResourceLoaderAware获取 ResourceLoader,用于加载类路径或文件系统中的资源。
ApplicationEventPublisherAware获取事件发布器(ApplicationEventPublisher),用于发布应用事件。
MessageSourceAware获取 MessageSource,用于国际化消息处理。
ApplicationContextAware获取 ApplicationContext,访问容器的完整功能(如事件发布、环境变量、资源加载等)。
ServletContextAware (Web)获取 Servlet 容器的上下文对象(ServletContext),仅限 Web 应用。
ServletConfigAware (Web)获取 Servlet 配置对象(ServletConfig),仅限 Web 应用。

2. Aware 接口的执行顺序
在 Bean 的生命周期中,Aware 接口的回调发生在 属性注入之后、初始化方法(如 @PostConstruct)之前。具体执行顺序如下:

  1. BeanNameAware
    设置 Bean 的名称。

  2. BeanClassLoaderAware
    设置类加载器。

  3. BeanFactoryAware
    设置 BeanFactory 实例。

  4. EnvironmentAware
    注入环境变量配置。

  5. EmbeddedValueResolverAware
    提供占位符解析能力。

  6. ResourceLoaderAware
    设置资源加载器(仅在 ApplicationContext 中有效)。

  7. ApplicationEventPublisherAware
    注入事件发布器。

  8. MessageSourceAware
    设置国际化消息源。

  9. ApplicationContextAware
    注入完整的应用上下文。

  10. Web 相关 Aware 接口(如 ServletContextAwareServletConfigAware
    在 Web 应用中,这些接口的回调通常发生在 ApplicationContextAware 之后。


3. 验证执行顺序的示例

@Component
public class AllAwareBean implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware,EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware {@Overridepublic void setBeanName(String name) {System.out.println("1. BeanNameAware: " + name);}@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println("2. BeanClassLoaderAware");}@Overridepublic void setBeanFactory(BeanFactory beanFactory) {System.out.println("3. BeanFactoryAware");}@Overridepublic void setEnvironment(Environment environment) {System.out.println("4. EnvironmentAware");}@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {System.out.println("5. EmbeddedValueResolverAware");}@Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {System.out.println("6. ResourceLoaderAware");}@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {System.out.println("7. ApplicationEventPublisherAware");}@Overridepublic void setMessageSource(MessageSource messageSource) {System.out.println("8. MessageSourceAware");}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) {System.out.println("9. ApplicationContextAware");}
}

输出结果

1. BeanNameAware: allAwareBean
2. BeanClassLoaderAware
3. BeanFactoryAware
4. EnvironmentAware
5. EmbeddedValueResolverAware
6. ResourceLoaderAware
7. ApplicationEventPublisherAware
8. MessageSourceAware
9. ApplicationContextAware

4. 注意事项

  • Web 相关接口的执行时机
    在 Spring Boot Web 应用中,ServletContextAwareServletConfigAware 的回调发生在 ApplicationContextAware 之后,具体顺序可能因容器启动流程略有差异。

  • 避免依赖顺序
    虽然顺序是固定的,但业务代码应避免依赖具体执行顺序,以保持灵活性和可维护性。

  • 替代方案
    优先使用依赖注入(如 @Autowired)而非 Aware 接口,以减少与 Spring API 的耦合。例如,直接注入 ApplicationContext

    @Autowired
    private ApplicationContext context;
    

5. 总结
Spring Boot 中的 Aware 接口允许 Bean 感知容器环境,其执行顺序遵循 Spring Framework 的规范。核心接口按 BeanNameAwareBeanClassLoaderAwareBeanFactoryAwareEnvironmentAware → … → ApplicationContextAware 的顺序依次触发。理解这一顺序有助于在需要精确控制初始化逻辑时合理使用这些接口。









在Spring Boot中,提供了多种Aware接口,这些接口允许Bean获取Spring容器中的特定资源或信息。以下是一些常见的Aware接口及其执行顺序:

一、常见的Aware接口

  1. BeanNameAware:实现该接口可以获取当前Bean的名称。
  2. BeanClassLoaderAware:实现该接口可以获取当前Bean的类加载器。
  3. BeanFactoryAware:实现该接口可以获取当前Spring的BeanFactory,从而以编程方式访问和操作容器中的Bean。
  4. EnvironmentAware:实现该接口可以获取当前应用程序的Environment,从而访问配置属性、配置文件等与应用程序配置相关的信息。
  5. EmbeddedValueResolverAware:实现该接口可以获取字符串解析器,用于解析嵌入的值(如${property}形式的占位符)。
  6. ResourceLoaderAware:实现该接口可以获取ResourceLoader,从而加载外部资源,如文件、类路径资源等。
  7. ApplicationEventPublisherAware:实现该接口可以获取ApplicationEventPublisher,从而发布应用程序事件。
  8. MessageSourceAware:实现该接口可以获取MessageSource,从而获取国际化消息。
  9. ApplicationContextAware:实现该接口可以获取当前应用程序的ApplicationContext,从而访问和操作Spring容器中的Bean以及其他上下文信息。
  10. ServletContextAware:在Web应用程序中,实现该接口可以获取ServletContext,从而访问Web应用程序的上下文信息(仅适用于Web应用程序上下文)。
  11. LoadTimeWeaverAware:在使用@EnableLoadTimeWeaving或存在LoadTimeWeaver实现的Bean时,实现该接口可以获取LoadTimeWeaver,从而进行类转换等高级操作。
  12. ImportAware:在被其他配置类@Import导入时,实现该接口可以获取导入的元数据。

二、Aware接口的执行顺序

在Spring容器启动并创建Bean的过程中,如果Bean实现了上述的Aware接口,Spring容器会在适当的时机调用对应的回调方法,将相关的资源或信息传递给Bean。这些Aware接口的执行顺序通常如下:

  1. BeanNameAware#setBeanName:首先调用,设置Bean的名称。
  2. BeanClassLoaderAware#setBeanClassLoader:接着调用,设置Bean的类加载器。
  3. BeanFactoryAware#setBeanFactory:然后调用,设置BeanFactory。
  4. ResourceLoaderAware#setResourceLoader(仅当在应用程序上下文中运行时):设置ResourceLoader。
  5. ApplicationEventPublisherAware#setApplicationEventPublisher(仅当在应用程序上下文中运行时):设置ApplicationEventPublisher。
  6. MessageSourceAware#setMessageSource(仅当在应用程序上下文中运行时):设置MessageSource。
  7. ApplicationContextAware#setApplicationContext(仅当在应用程序上下文中运行时):设置ApplicationContext。
  8. EmbeddedValueResolverAware#setEmbeddedValueResolver:设置字符串解析器。
  9. ServletContextAware#setServletContext(仅当在Web应用程序上下文中运行时):设置ServletContext。

需要注意的是,LoadTimeWeaverAwareImportAware的执行顺序相对特殊:

  • LoadTimeWeaverAware#setLoadTimeWeaver:仅在使用@EnableLoadTimeWeaving或存在LoadTimeWeaver实现的Bean时才会调用,且顺序较靠后。
  • ImportAware#setImportMetadata:仅在被其他配置类@Import导入时才会调用,且这个调用通常针对的是被导入配置类中的Bean,其执行顺序与其他Aware接口可能不同。

此外,Spring容器内部会维护一个集合,记录所有实现了Aware接口的Bean,并在适当的生命周期阶段(如Bean的实例化后、属性注入前或初始化前)遍历这个集合,为每个实现了Aware接口的Bean调用相应的回调方法。

综上所述,了解Spring Boot中的Aware接口及其执行顺序对于开发者来说非常重要,因为这有助于开发者在Bean生命周期的各个阶段获取所需的资源或信息,从而实现特定的业务逻辑或功能扩展。









Spring Boot 继承了 Spring Framework 的所有特性,包括 Aware 接口。因此,在 Spring Boot 中可以使用 Spring Framework 提供的所有标准 Aware 接口。这些接口允许 Bean 在初始化过程中获取到 Spring 容器或容器中的特定资源。

以下是 Spring 和 Spring Boot 中常见的 Aware 接口:

  • BeanNameAware:让 Bean 获得它在容器中定义的名称。
  • BeanClassLoaderAware:提供给 Bean 获取加载其类的 ClassLoader。
  • BeanFactoryAware:让 Bean 获取创建它的 BeanFactory 实例。
  • ApplicationContextAware:让 Bean 获取当前的应用上下文 ApplicationContext。
  • EnvironmentAware:让 Bean 获取 Environment 对象,用于访问配置属性和环境变量。
  • EmbeddedValueResolverAware:为 Bean 提供一个可用于解析占位符的值解析器。
  • ResourceLoaderAware:让 Bean 获取 ResourceLoader 以便加载外部资源文件。
  • ApplicationEventPublisherAware:让 Bean 获取 ApplicationEventPublisher 以发布应用事件。
  • MessageSourceAware:让 Bean 获取 MessageSource 用于国际化文本信息。
  • ServletContextAwareServletConfigAware:仅适用于 Web 应用程序,分别提供 Servlet 上下文和配置对象。

至于 Aware 接口的执行顺序,通常是在 Bean 初始化的过程中按照以下顺序调用:

  1. 如果实现了 BeanNameAware,则会调用 setBeanName(String name) 方法。
  2. 如果实现了 BeanClassLoaderAware,则会调用 setBeanClassLoader(ClassLoader classLoader) 方法。
  3. 如果实现了 BeanFactoryAware,则会调用 setBeanFactory(BeanFactory beanFactory) 方法。
  4. 然后是 EnvironmentAwareEmbeddedValueResolverAwareResourceLoaderAwareApplicationEventPublisherAwareMessageSourceAwareApplicationContextAware 接口对应的方法依次被调用。

这个顺序是由 Spring 框架内部逻辑决定的,并且是在 AbstractAutowireCapableBeanFactory 类中的 initializeBean 方法里处理的。具体来说,在 invokeAwareMethods 方法中处理直接方法调用(如 BeanNameAware, BeanClassLoaderAware, BeanFactoryAware),而在 ApplicationContextAwareProcessor 类中通过 invokeAwareInterfaces 方法处理那些需要 BeanPostProcessor 来触发的回调(如 EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware)。

请注意,ServletContextAwareServletConfigAware 的回调是由 ServletContextAwareProcessor 处理的,这可能与上述其他接口的处理方式不同。

综上所述,Spring Boot 使用的是 Spring Framework 的 Aware 接口机制,它们的执行顺序是固定的,并由 Spring 内部逻辑控制。开发者只需要实现相应的 Aware 接口并提供相应的设置方法即可利用这一机制来访问 Spring 容器提供的各种服务和资源。









在Spring Boot中,Aware接口是一系列特殊的接口,实现这些接口的Bean可以在Spring容器中感知到特定的对象或信息。下面为你介绍常见的Aware接口及其执行顺序。

常见的Aware接口

1. BeanNameAware

  • 作用:实现该接口的Bean可以获取到自身在Spring容器中的名称。
  • 示例代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;@Component
public class MyBeanNameAware implements BeanNameAware {@Overridepublic void setBeanName(String name) {System.out.println("Bean的名称是: " + name);}
}

2. BeanClassLoaderAware

  • 作用:实现该接口的Bean可以获取到加载该Bean的类加载器。
  • 示例代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.stereotype.Component;@Component
public class MyBeanClassLoaderAware implements BeanClassLoaderAware {@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println("加载Bean的类加载器是: " + classLoader);}
}

3. BeanFactoryAware

  • 作用:实现该接口的Bean可以获取到创建它的BeanFactory
  • 示例代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;@Component
public class MyBeanFactoryAware implements BeanFactoryAware {@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("创建Bean的BeanFactory是: " + beanFactory);}
}

4. EnvironmentAware

  • 作用:实现该接口的Bean可以获取到Spring的Environment对象,通过该对象可以获取配置信息等。
  • 示例代码
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;@Component
public class MyEnvironmentAware implements EnvironmentAware {@Overridepublic void setEnvironment(Environment environment) {System.out.println("当前的环境配置是: " + environment);}
}

5. EmbeddedValueResolverAware

  • 作用:实现该接口的Bean可以获取到一个StringValueResolver对象,用于解析占位符。
  • 示例代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;@Component
public class MyEmbeddedValueResolverAware implements EmbeddedValueResolverAware {private StringValueResolver resolver;@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {this.resolver = resolver;String resolvedValue = resolver.resolveStringValue("${my.property:default}");System.out.println("解析后的属性值是: " + resolvedValue);}
}

6. ResourceLoaderAware

  • 作用:实现该接口的Bean可以获取到ResourceLoader对象,用于加载资源。
  • 示例代码
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;@Component
public class MyResourceLoaderAware implements ResourceLoaderAware {@Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {Resource resource = resourceLoader.getResource("classpath:application.properties");System.out.println("加载的资源是: " + resource);}
}

7. ApplicationEventPublisherAware

  • 作用:实现该接口的Bean可以获取到ApplicationEventPublisher对象,用于发布应用程序事件。
  • 示例代码
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;@Component
public class MyApplicationEventPublisherAware implements ApplicationEventPublisherAware {private ApplicationEventPublisher publisher;@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher publisher) {this.publisher = publisher;// 发布事件// publisher.publishEvent(new MyCustomEvent(this));}
}

8. ApplicationContextAware

  • 作用:实现该接口的Bean可以获取到ApplicationContext对象,通过该对象可以获取更多的Spring容器信息。
  • 示例代码
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class MyApplicationContextAware implements ApplicationContextAware {@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("当前的ApplicationContext是: " + applicationContext);}
}

执行顺序
这些Aware接口的执行顺序大致如下:

  1. BeanNameAware
  2. BeanClassLoaderAware
  3. BeanFactoryAware
  4. EnvironmentAware
  5. EmbeddedValueResolverAware
  6. ResourceLoaderAware
  7. ApplicationEventPublisherAware
  8. ApplicationContextAware

需要注意的是,这个顺序并不是绝对固定的,可能会受到Spring版本、配置等因素的影响,但总体上遵循上述的先后顺序。这些Aware接口为开发者提供了在Spring容器中获取特定信息和对象的便捷方式,方便对Bean进行定制化的操作。









在Spring Boot中,Aware接口是一系列能够让Bean感知到某些容器级别或者环境级别的信息的重要工具。通过实现这些接口,开发者可以让他们的组件获得诸如应用上下文、bean工厂等相关服务而不必显式传递依赖项。

常见的 Aware 接口

下面列出了一些常用的Aware接口及其功能描述:

  1. ApplicationContextAware

    • 让Bean可以获得对当前应用程序上下文(Application Context)对象的引用。
  2. BeanFactoryAware

    • 允许访问底层Bean工厂(Bean Factory),这对于更细粒度的操作很有帮助。
  3. BeanNameAware

    • 提供了获取自身名称的功能,在配置阶段非常有用。
  4. EnvironmentAware

    • 获取有关部署环境的信息,比如激活的profile、系统属性等等。
  5. EmbeddedValueResolverAware

    • 支持解析嵌入式的占位符(${...}形式),可以在代码里动态地替换为实际值。
  6. MessageSourceAware

    • 能够让Bean读取消息源中的国际化内容或其他文本资源。
  7. ResourceLoaderAware

    • 给予Bean加载物理文件的能力,无论是来自本地磁盘还是远程HTTP URL等位置。
  8. ServletConfigAware, ServletContextAware

    • 分别用于Web环境中取得Servlet配置或全局Context的相关细节。
  9. ApplicationEventPublisherAware

    • 可以发布事件(Event Publisher),有助于松耦合的应用设计。

执行顺序

当一个Bean同时实现了多个Aware接口时,Spring会在初始化过程中按一定的优先级依次调用各个接口对应的回调方法。根据官方文档说明,具体的执行顺序大致如下:

  1. PostProcessBeforeInstantiation – 由所有注册过的BeanPostProcessor提供的前置处理机会。(不是严格的Aware部分)
  2. setBeanName(String name) —> 来自BeanNameAware
  3. setBeanClassLoader(ClassLoader classLoader) -> 自动完成
  4. setBeanFactory(BeanFactory beanFactory) -> 来自BeanFactoryAware
  5. setApplicationContext(ApplicationContext applicationContext) -> 来自ApplicationContextAware
  6. setEnvironment(Environment environment) -> 来自EnvironmentAware
  7. setEmbeddedValueResolver/StringValueResolver embeddedValueResolver/stringValueResolver) -> 来自EmbeddedValueResolverAware
  8. setMessageSource(MessageSource messageSource) -> 来自MessageSourceAware
  9. setResourceLoader(ResourceLoader resourceLoader) -> 来自ResourceLoaderAware
  10. setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) -> 来自ApplicationEventPublisherAware

请注意这里的列表并不是详尽无遗,并且还存在其他的一些特殊场景下才会触发的方法调用(例如与WebSocket相关的HandshakeInterceptor)。但对于大多数常规情况而言,上述就是常见的Aware接口及其实现顺序了。

如果你想要改变默认的行为或是添加更多定制化的逻辑,那么你可以考虑编写自己的BeanPostProcessor来介入这个过程。
























ServletConfigAware

在 Spring 框架中,ServletConfigAware 是一个专为 Web 应用设计的接口,允许 Bean 获取与当前 Servlet 相关的配置信息(ServletConfig 对象)。该接口主要用于访问 Servlet 的初始化参数和配置细节。以下是关于 ServletConfigAware 的详细说明:


1. ServletConfigAware 的作用

  • 获取 ServletConfig 对象:通过该接口,Bean 可以访问当前 Servlet 的配置信息。
  • 访问 Servlet 初始化参数:读取在 web.xml 或 Servlet 注解中定义的初始化参数(如数据库连接配置)。
  • 获取 Servlet 名称:访问当前 Servlet 的名称(<servlet-name> 或注解配置的 name)。

2. 接口定义
ServletConfigAware 接口定义如下:

public interface ServletConfigAware {void setServletConfig(ServletConfig servletConfig);
}

实现该接口的 Bean 必须重写 setServletConfig 方法,Spring 容器会在初始化阶段自动注入 ServletConfig 对象。


3. 使用示例
(1) 实现 ServletConfigAware

import javax.servlet.ServletConfig;
import org.springframework.web.context.ServletConfigAware;
import org.springframework.stereotype.Component;@Component
public class MyServletConfigAwareBean implements ServletConfigAware {private ServletConfig servletConfig;@Overridepublic void setServletConfig(ServletConfig servletConfig) {this.servletConfig = servletConfig;System.out.println("ServletConfig 已注入!");}// 使用 ServletConfig 获取初始化参数public String getInitParameter(String key) {return servletConfig.getInitParameter(key);}// 获取 Servlet 名称public String getServletName() {return servletConfig.getServletName();}
}

(2) 配置 Servlet 初始化参数
web.xml 中定义 Servlet 并设置初始化参数:

<servlet><servlet-name>myServlet</servlet-name><servlet-class>com.example.MyServlet</servlet-class><init-param><param-name>db.url</param-name><param-value>jdbc:mysql://localhost:3306/mydb</param-value></init-param>
</servlet>

或在 Java 配置类中使用 @WebServlet 注解(Servlet 3.0+):

@WebServlet(name = "myServlet",urlPatterns = "/myservlet",initParams = {@WebInitParam(name = "db.url", value = "jdbc:mysql://localhost:3306/mydb")}
)
public class MyServlet extends HttpServlet {// ...
}

(3) 使用 Bean 获取参数

@Autowired
private MyServletConfigAwareBean configBean;public void printConfig() {String dbUrl = configBean.getInitParameter("db.url");String servletName = configBean.getServletName();System.out.println("Servlet Name: " + servletName);System.out.println("DB URL: " + dbUrl);
}

4. 执行时机

  • 触发阶段setServletConfig() 方法在 Bean 生命周期的 Aware 接口回调阶段 执行。
  • 执行顺序
    在 Spring Web 应用中,ServletConfigAware 的回调发生在以下阶段:
    1. BeanNameAware → 2. BeanClassLoaderAware → ... → 9. ApplicationContextAware → 10. ServletContextAware → 11. ServletConfigAware
    
  • 依赖条件
    只有在 DispatcherServlet 初始化完成后ServletConfig 才会被注入。确保 Bean 的作用域为 Singleton,并在 Web 上下文中使用。

5. 注意事项
(1) 仅限 Web 应用

  • ServletConfigAware 仅在 Spring Web 应用中有效(如使用 DispatcherServlet 的 Spring MVC 或 Spring Boot Web 应用)。
  • 在非 Web 环境(如单元测试或独立应用)中使用会抛出异常。

(2) 避免与 ServletContextAware 混淆

接口作用范围获取对象典型用途
ServletConfigAware单个 ServletServletConfig读取当前 Servlet 的初始化参数
ServletContextAware整个 Web 应用ServletContext访问应用级别的资源(如全局属性、上下文路径)

(3) 替代方案

  • 推荐使用依赖注入
    在 Spring Boot 中,优先通过 @ValueEnvironment 对象获取配置,而非直接依赖 ServletConfig
    @Value("${db.url}")
    private String dbUrl;
    
  • 使用 @WebServlet 注解
    在 Servlet 3.0+ 中,可直接在 Servlet 类中通过 @WebInitParam 定义参数,无需额外配置。

(4) 作用域限制

  • 仅适用于 Singleton Bean
    Prototype 作用域的 Bean 可能无法正确获取 ServletConfig,因为其生命周期不受容器完全管理。

6. 常见问题
Q1: 为何 setServletConfig() 方法中的 servletConfignull

  • 可能原因
    • Bean 未在 Web 上下文中注册(如未启用 Spring MVC)。
    • 在非 Servlet 环境(如单元测试)中使用。
    • 未正确配置 DispatcherServlet。

Q2: 如何获取其他 Servlet 的 ServletConfig

  • 直接获取不可行ServletConfigAware 仅注入当前 Servlet 的配置。
  • 替代方案:通过 ServletContext 获取其他 Servlet 的配置:
    ServletConfig otherServletConfig = servletContext.getServletRegistration("otherServlet").getServletConfig();
    

7. 总结

  • 核心作用ServletConfigAware 允许 Bean 访问当前 Servlet 的配置信息(ServletConfig)。
  • 适用场景:需读取 Servlet 初始化参数或获取 Servlet 名称的 Web 应用。
  • 最佳实践:在 Spring Boot 中优先使用 @ValueEnvironment,减少对 Servlet API 的直接依赖。









ServletConfig是Java Servlet API中的一个接口,它代表了当前Servlet在web.xml配置文件中的配置信息。以下是对ServletConfig的详细解析:

一、定义与作用

ServletConfig接口为Servlet提供初始配置参数的一种对象。每个Servlet在容器中运行时,容器都会为其创建一个唯一的ServletConfig对象,该对象包含了Servlet在部署描述符(如web.xml)中指定的配置信息。

二、主要功能

ServletConfig接口的主要功能包括:

  1. 获取Servlet的配置名称:通过getServletName()方法,可以获取到当前Servlet在web.xml配置文件中对应的<servlet-name>标签的值。
  2. 获取Servlet的初始化参数:Servlet的初始化参数是在web.xml配置文件中通过<init-param>标签设置的。ServletConfig接口提供了getInitParameter(String name)方法,用于根据参数名获取对应的参数值。此外,还可以通过getInitParameterNames()方法获取所有初始化参数的名称枚举。
  3. 获取ServletContext对象:ServletContext对象代表了整个Web应用的全局环境,为所有的Servlet所共享。ServletConfig接口提供了getServletContext()方法,用于获取与该Servlet关联的ServletContext对象。

三、使用场景

ServletConfig通常在Servlet的init(ServletConfig config)方法中被使用。当Servlet容器创建Servlet实例并调用其init方法时,会将ServletConfig对象作为参数传递给该方法。Servlet开发者可以在init方法中通过该参数获取Servlet的配置信息,并进行相应的初始化操作。

此外,在Servlet的其他生命周期方法中(如servicedoGetdoPost等),也可以通过调用this.getServletConfig()方法获取到ServletConfig对象,进而获取配置信息。但需要注意的是,由于每个Servlet实例只有一个对应的ServletConfig对象,因此通常不需要在每次请求处理中都重新获取它。

四、示例代码

以下是一个简单的示例,展示了如何在Servlet中使用ServletConfig接口获取配置信息:

import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyServlet extends HttpServlet {@Overridepublic void init(ServletConfig config) throws ServletException {super.init(config);// 获取Servlet配置名称String servletName = config.getServletName();System.out.println("Servlet Name: " + servletName);// 获取并打印所有初始化参数Enumeration<String> initParameterNames = config.getInitParameterNames();while (initParameterNames.hasMoreElements()) {String paramName = initParameterNames.nextElement();String paramValue = config.getInitParameter(paramName);System.out.println(paramName + ": " + paramValue);}// 获取ServletContext对象ServletContext context = config.getServletContext();// 可以对context进行进一步操作...}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 在doGet方法中也可以使用ServletConfig对象(但通常不需要重新获取)ServletConfig config = this.getServletConfig();String someParam = config.getInitParameter("someParamName");// 对someParam进行进一步处理...response.getWriter().println("Hello, ServletConfig!");}// 其他生命周期方法和业务逻辑方法...
}

在上面的示例中,MyServlet类继承自HttpServlet,并重写了initdoGet方法。在init方法中,通过传入的ServletConfig对象获取了Servlet的配置名称和所有初始化参数,并打印了出来。在doGet方法中,虽然也可以通过this.getServletConfig()方法获取到ServletConfig对象,但通常不需要这样做,因为每个Servlet实例只有一个对应的ServletConfig对象。









ServletConfigAware 是 Spring 框架中的一个接口,主要用于让实现它的类获取当前 Servlet 配置(ServletConfig)的引用。在传统的 Spring 应用中,特别是在基于 Servlet 的 Web 应用程序里,这个接口允许开发者访问与特定 Servlet 相关的配置信息。

使用场景

当你需要访问 ServletConfig 对象来读取初始化参数或获取 Servlet 上下文时,可以使用 ServletConfigAware 接口。通过实现此接口,你可以得到 ServletConfig 实例,并从中提取出你所需要的配置数据。

示例代码

下面是一个简单的示例,展示了如何实现 ServletConfigAware 接口:

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ServletConfigAware;
import javax.servlet.ServletConfig;public class MyServletConfigAwareBean implements ServletConfigAware {private ServletConfig servletConfig;@Overridepublic void setServletConfig(ServletConfig servletConfig) {this.servletConfig = servletConfig;}public void printServletInitParameter() {// 从servlet配置中获取初始化参数String initParamValue = servletConfig.getInitParameter("some-param");System.out.println("Servlet init parameter value: " + initParamValue);}
}

在这个例子中,MyServletConfigAwareBean 类实现了 ServletConfigAware 接口,并重写了 setServletConfig(ServletConfig servletConfig) 方法。这样,在 Spring 容器创建该 Bean 的时候,它会自动调用这个方法并传入 ServletConfig 实例。之后,你就可以使用这个实例来获取初始化参数或其他配置信息了。

注意事项

值得注意的是,ServletConfigAware 只适用于传统的基于 Servlet API 的 Web 应用程序。如果你是在 Spring Boot 中开发应用程序,通常不需要直接使用 ServletConfigAware,因为 Spring Boot 更倾向于隐藏底层 Servlet API 的细节,提供更高层次的抽象和服务。

另外,根据 Spring 内部的执行逻辑,ServletConfigAware 接口的方法会在 Bean 初始化的过程中被调用,其顺序是在其他一些 Aware 接口(如 ApplicationContextAware)之后。这是因为在 Spring 中,这些接口的回调是由不同的处理器来处理的,对于 ServletConfigAwareServletContextAware,它们是通过 ServletContextAwareProcessor 来处理的。
















Springboot为什么不调用ServletConfigAware?

ServletConfigAware的源码:

/** Copyright 2002-2018 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.web.context;import jakarta.servlet.ServletConfig;import org.springframework.beans.factory.Aware;/*** Interface to be implemented by any object that wishes to be notified of the* {@link ServletConfig} (typically determined by the {@link WebApplicationContext})* that it runs in.** <p>Note: Only satisfied if actually running within a Servlet-specific* WebApplicationContext. Otherwise, no ServletConfig will be set.** @author Juergen Hoeller* @author Chris Beams* @since 2.0* @see ServletContextAware*/
public interface ServletConfigAware extends Aware {/*** Set the {@link ServletConfig} that this object runs in.* <p>Invoked after population of normal bean properties but before an init* callback like InitializingBean's {@code afterPropertiesSet} or a* custom init-method. Invoked after ApplicationContextAware's* {@code setApplicationContext}.* @param servletConfig the {@link ServletConfig} to be used by this object* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet* @see org.springframework.context.ApplicationContextAware#setApplicationContext*/void setServletConfig(ServletConfig servletConfig);}

有这么一段说明

Only satisfied if actually running within a Servlet-specific *
WebApplicationContext. Otherwise, no ServletConfig will be set.

确实,ServletConfigAware接口仅在运行于特定的Servlet WebApplicationContext环境下时才会被满足。这意味着如果你的应用程序不是部署在一个基于Servlet API的环境中,或者没有使用Spring的WebApplicationContext(例如,在一个非Web的Spring应用中),那么就不会有ServletConfig被设置给实现了ServletConfigAware接口的Bean。

Servlet WebApplicationContext

在传统的Spring MVC或任何基于Servlet API的Web应用程序中,Spring会创建一个特殊的WebApplicationContext实例,通常是一个XmlWebApplicationContext或其子类,如AnnotationConfigWebApplicationContext。这个上下文是ApplicationContext的一个特殊版本,它不仅提供了标准的IoC容器功能,还额外包含了对Web环境的支持,比如能够访问ServletContextServletConfig对象。

当你使用Spring Boot构建一个Web应用程序时,默认情况下它也会创建一个WebApplicationContext,并且如果需要的话,可以自动配置并嵌入一个Servlet容器(如Tomcat)。然而,Spring Boot的设计目标之一是尽量减少开发者对底层Servlet API的直接依赖,因此许多时候你不需要也不应该直接与Servlet API交互。

没有ServletConfig的情况

  • 非Web环境:如果你的应用不是Web应用,则不会存在ServletConfig对象,因为这是专门为Servlet环境设计的概念。

  • 未正确配置WebApplicationContext:即使是在Web环境中,如果你的应用程序没有正确地初始化WebApplicationContext,也可能导致ServletConfig无法被注入到实现了ServletConfigAware接口的Bean中。

  • 内嵌Servlet容器的特殊情况:虽然Spring Boot支持内嵌Servlet容器,但在某些情况下,特别是当你的应用不严格遵循传统Servlet规范时,可能会出现ServletConfig未被设置的情况。

解决方案

如果你的应用确实需要访问ServletConfig,确保以下几点:

  1. 应用程序是以Web应用的形式启动的,并且正确配置了WebApplicationContext
  2. 如果你正在使用Spring Boot,确保你已经添加了必要的Web依赖(例如spring-boot-starter-web)。
  3. 确认你的Bean是在正确的上下文中被创建的,即该上下文是由WebApplicationContext派生出来的。

此外,正如前面提到的,如果你只是需要访问ServletContext而不是ServletConfig,你可以实现ServletContextAware接口,或者通过构造函数/字段注入的方式获得ServletContext实例。

总结来说,ServletConfigAware只适用于基于Servlet API的Web应用程序,并且只有在这样的环境中,Spring才会尝试将ServletConfig对象注入到实现了此接口的Bean中。如果不是这种情况,那么你就不能指望ServletConfig会被设置。









确实,ServletConfigAware 接口的实现只有在实际上运行于 Servlet 特定的 WebApplicationContext 中时,其 setServletConfig(ServletConfig servletConfig) 方法才会被 Spring 容器调用以设置 ServletConfig 对象。如果 Bean 不是在 Servlet 环境中运行,或者不是在由 Spring 管理的 WebApplicationContext 中,那么 ServletConfig 将不会被设置。

在 Spring Boot 应用中,这通常意味着以下几点:

  1. 依赖管理:确保你的项目中包含了 Spring Web 的依赖(如 spring-boot-starter-web),这会自动引入 Servlet 容器(默认是 Tomcat)和相关的 Spring Web 组件。

  2. Bean 的定义:你的 ServletConfigAware 实现类需要被 Spring 容器管理。这通常通过添加如 @Component@Service 或直接在配置类中通过 @Bean 方法定义来实现。

  3. WebApplicationContext:Spring Boot 会自动为你创建一个 AnnotationConfigServletWebServerApplicationContext(这是 WebApplicationContext 的一个实现),它包含了 Servlet 特定的配置和上下文信息。只要你的应用是作为 Servlet Web 应用运行的,这个上下文就会被正确设置。

  4. 运行环境:确保你的应用是在一个 Servlet 容器中运行的。在 Spring Boot 中,这通常意味着你运行的是一个打包成 JAR 或 WAR 的应用,该应用被部署到了一个 Servlet 容器(如 Tomcat、Jetty 或 Undertow)中,或者你直接通过 Spring Boot 的内嵌 Servlet 容器运行应用。

  5. 配置覆盖:如果你自定义了 Spring Boot 的配置,确保你没有不小心覆盖了关于 WebApplicationContext 或 Servlet 容器的自动配置。

如果你遵循了上述所有步骤,但 ServletConfigAwaresetServletConfig 方法仍然没有被调用,那么可能的问题包括:

  • 你的 Bean 可能没有被正确地注册到 Spring 容器中。
  • 你的应用可能没有作为 Servlet Web 应用运行(例如,它可能是一个非 Web 的 Spring 应用)。
  • 你可能覆盖了 Spring Boot 的某些自动配置,导致 WebApplicationContext 没有被正确设置。

为了诊断问题,你可以:

  • 检查你的 Spring Boot 应用是否确实包含了 Web 依赖。
  • 确保你的 ServletConfigAware 实现类上有正确的 Spring 注解。
  • 添加日志记录到你的 setServletConfig 方法中,以查看该方法是否确实被调用。
  • 检查你的 Spring Boot 配置,确保没有覆盖关于 Web 组件的自动配置。
  • 如果你的应用是作为 WAR 部署的,确保你的 application.propertiesapplication.yml 配置文件中没有设置 server.port 或其他与内嵌 Servlet 容器相关的属性,因为这些属性在 WAR 部署模式下通常是不需要的。









英文释义
这段英文的意思是:“仅当在特定于 Servlet 的 WebApplicationContext 中实际运行时,此操作才会生效。否则,不会设置 ServletConfig。”

含义解读
1. Servlet - specific WebApplicationContext
在 Java Web 开发中,Spring 的 WebApplicationContextApplicationContext 的一个子接口,专门用于 Web 环境。而“特定于 Servlet 的 WebApplicationContext”意味着这个上下文是和 Servlet 紧密关联的,它通常包含了与 Servlet 相关的环境信息,比如 Servlet 容器的上下文、Servlet 配置等。

2. ServletConfig
ServletConfig 是 Java Servlet 规范中的一个接口,它提供了 Servlet 的配置信息,包括初始化参数、Servlet 名称等。Servlet 容器在启动 Servlet 时会创建一个 ServletConfig 对象,并将其传递给 Servlet 的 init 方法。

3. 条件限制
这段描述表明,某个操作(可能是某个 Bean 的初始化方法、某个配置的设置等)依赖于运行在 Servlet 相关的 Web 环境中。如果当前的应用上下文不是一个特定于 Servlet 的 WebApplicationContext,那么就不会设置 ServletConfig。这是一种安全机制,确保只有在合适的环境中才进行相关操作,避免在非 Web 环境或者不支持 Servlet 的环境中出现错误。

代码示例说明
以下是一个简单的示例,展示了在 Spring 中如何根据是否为 WebApplicationContext 来设置 ServletConfig

import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;public class MyBean implements InitializingBean {private ServletConfig servletConfig;private ApplicationContext applicationContext;public MyBean(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}@Overridepublic void afterPropertiesSet() throws Exception {if (applicationContext instanceof WebApplicationContext) {WebApplicationContext webApplicationContext = (WebApplicationContext) applicationContext;ServletContext servletContext = webApplicationContext.getServletContext();// 假设这里可以通过某种方式获取 ServletConfig// 实际情况中,ServletConfig 通常由 Servlet 容器在 Servlet 初始化时提供// 这里只是示例逻辑// this.servletConfig = ... System.out.println("ServletConfig 已设置");} else {System.out.println("不是 WebApplicationContext,不设置 ServletConfig");}}public ServletConfig getServletConfig() {return servletConfig;}
}

在这个示例中,MyBean 实现了 InitializingBean 接口,在 afterPropertiesSet 方法中检查当前的 ApplicationContext 是否为 WebApplicationContext,如果是则尝试设置 ServletConfig,否则不进行设置。









在 Spring Boot 应用中,若实现 ServletConfigAware 接口但未触发其回调方法,通常是因为应用未运行在 Servlet 特定的 Web 应用上下文 环境中。以下是逐步排查与解决方案:


1. 确认应用为 Servlet Web 应用
1.1 检查依赖
确保项目中包含 spring-boot-starter-web 依赖(Maven):

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

或(Gradle):

implementation 'org.springframework.boot:spring-boot-starter-web'

1.2 验证启动日志
启动应用时,检查日志中是否输出嵌入式 Servlet 容器(如 Tomcat)的初始化信息:

o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)

1.3 检查主类配置
确保主类使用 @SpringBootApplication 并启动 Spring Boot 应用:

@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

2. 确认 Bean 注册与作用域
2.1 确保 Bean 被扫描
实现 ServletConfigAware 的类需添加组件注解(如 @Component):

@Component
public class MyServletConfigAwareBean implements ServletConfigAware {@Overridepublic void setServletConfig(ServletConfig servletConfig) {System.out.println("ServletConfig 已注入!");}
}

2.2 检查作用域
确保 Bean 的作用域为 Singleton(默认值):

@Scope("singleton") // 可选,默认即为 Singleton
@Component
public class MyServletConfigAwareBean implements ServletConfigAware {// ...
}

3. 验证应用上下文类型
3.1 获取应用上下文类型
在 Bean 中打印应用上下文类型,确认是否为 ServletWebServerApplicationContext

@Autowired
private ApplicationContext context;@PostConstruct
public void checkContextType() {System.out.println("应用上下文类型: " + context.getClass().getName());// 预期输出: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
}

3.2 非 Web 环境下的表现
若应用未启用 Web 功能,上下文类型将为非 Servlet 类型(如 AnnotationConfigApplicationContext),导致 ServletConfigAware 失效。


4. 处理测试环境问题
4.1 单元测试中的配置
在测试类中,确保使用 @SpringBootTest 并设置 Web 环境:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyWebTest {// ...
}

4.2 避免模拟 Servlet 环境
若测试中未启动真实 Servlet 容器(如使用 MockMvc),ServletConfig 将不可用。


5. 替代方案
5.1 使用 ServletContextAware 替代
通过 ServletContext 获取初始化参数:

@Component
public class MyServletContextAwareBean implements ServletContextAware {private ServletContext servletContext;@Overridepublic void setServletContext(ServletContext servletContext) {this.servletContext = servletContext;String param = servletContext.getInitParameter("myParam");System.out.println("参数值: " + param);}
}

5.2 通过 @Value 注入参数
application.properties 中定义参数:

my.init.param=jdbc:mysql://localhost:3306/mydb

在 Bean 中直接注入:

@Value("${my.init.param}")
private String initParam;

5.3 使用 Environment 对象

@Autowired
private Environment env;public void printParam() {String param = env.getProperty("my.init.param");System.out.println("参数值: " + param);
}

6. 总结

  • 根本原因ServletConfigAware 仅在 Servlet Web 应用上下文中有效,应用需正确配置为 Web 模式。
  • 解决步骤
    1. 添加 spring-boot-starter-web 依赖。
    2. 确保主类正确启动嵌入式 Servlet 容器。
    3. 验证 Bean 的注册与作用域。
    4. 在测试中配置 Web 环境。
  • 替代方案:优先使用 @ValueEnvironmentServletContextAware 避免依赖 ServletConfig

通过以上步骤,可确保 ServletConfigAware 在符合条件的环境中正确触发,或在必要时选择更可靠的配置注入方式。









本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/13575.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C基础寒假练习(6)

一、终端输入行数&#xff0c;打印倒金字塔 #include <stdio.h> int main() {int rows;printf("请输入倒金字塔的行数: ");scanf("%d", &rows);for (int i rows; i > 0; i--) {// 打印空格for (int j 0; j < rows - i; j) {printf(&qu…

使用 CSS 实现透明效果

在 CSS 中&#xff0c;实现透明效果有几种方法&#xff0c;具体使用哪种方法取决于具体需求。以下是一些常见的方法&#xff1a; 使用 opacity 属性&#xff1a; opacity 属性可以设置整个元素的透明度&#xff0c;包括其所有的子元素。 .transparent { opacity: 0.5; /* 0 表…

解锁反序列化漏洞:从原理到防护的安全指南

目录 前言 一、什么是反序列化 二、反序列化漏洞原理 三、反序列化漏洞的危害 &#xff08;一&#xff09;任意代码执行 &#xff08;二&#xff09;权限提升 &#xff08;三&#xff09;数据泄露与篡改 四、常见的反序列化漏洞场景 &#xff08;一&#xff09;PHP 反…

UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理

UE虚幻引擎No Google Play Store Key&#xff1a;No OBB found报错如何处理&#xff1f; 问题描述&#xff1a; UE成功打包APK并安装过后&#xff0c;启动应用时提示&#xff1a; No Google Play Store KeyNo OBB found and no store key to try to download. Please setone …

Text2Sql:开启自然语言与数据库交互新时代(3030)

一、Text2Sql 简介 在当今数字化时代&#xff0c;数据处理和分析的需求日益增长。对于众多非技术专业人员而言&#xff0c;数据库操作的复杂性常常成为他们获取所需信息的障碍。而 Text2Sql 技术的出现&#xff0c;为这一问题提供了有效的解决方案。 Text2Sql&#xff0c;即文…

八大排序算法细讲

目录 排序 概念 运用 常见排序算法 插入排序 直接插入排序 思想&#xff1a; 步骤&#xff08;排升序&#xff09;: 代码部分&#xff1a; 时间复杂度&#xff1a; 希尔排序 思路 步骤 gap的取法 代码部分&#xff1a; 时间复杂度&#xff1a; 选择排序 直接选…

基于MODIS/Landsat/Sentinel/国产卫星遥感数据与DSSAT作物模型同化的作物产量估算

基于过程的作物生长模拟模型DSSAT是现代农业系统研究的有力工具&#xff0c;可以定量描述作物生长发育和产量形成过程及其与气候因子、土壤环境、品种类型和技术措施之间的关系&#xff0c;为不同条件下作物生长发育及产量预测、栽培管理、环境评价以及未来气候变化评估等提供了…

【容器技术01】使用 busybox 构建 Mini Linux FS

使用 busybox 构建 Mini Linux FS 构建目标 在 Linux 文件系统下构建一个 Mini 的文件系统&#xff0c;构建目标如下&#xff1a; minilinux ├── bin │ ├── ls │ ├── top │ ├── ps │ ├── sh │ └── … ├── dev ├── etc │ ├── g…

排序算法与查找算法

1.十大经典排序算法 我们希望数据以一种有序的形式组织起来&#xff0c;无序的数据我们要尽量将其变得有序 一般说来有10种比较经典的排序算法 简单记忆为Miss D----D小姐 时间复杂度 &#xff1a;红色<绿色<蓝色 空间复杂度&#xff1a;圆越大越占空间 稳定性&…

使用多模态大语言模型进行深度学习的图像、文本和语音数据增强

在过去的五年里&#xff0c;研究方向已从传统的机器学习&#xff08;ML&#xff09;和深度学习&#xff08;DL&#xff09;方法转向利用大语言模型&#xff08;LLMs&#xff09;&#xff0c;包括多模态方法&#xff0c;用于数据增强&#xff0c;以提高泛化能力&#xff0c;并在…

PCA9685舵机控制板使用

1. 概述 PCA9685 是一款由 NXP 半导体公司生产的 16 通道 PWM 驱动器&#xff0c;广泛应用于多个舵机、LED 灯带控制等场景。它通过 I2C 总线与主控芯片&#xff08;如 STM32&#xff09;通信&#xff0c;可以高效地控制多个舵机的运动和多通道 PWM 输出。该模块适用于多舵机控…

2025.2.6(c++杂项补充及qt基础介绍)

作业 1> 完善C的思维导图 2> 重新创建一个新的项目&#xff0c;将默认提供的代码进行注释 3> QT的思维导图 4> 刷2个 98 C 牛客网上的题 笔记&#xff08;后期复习补上&#xff09;

Postgresql的三种备份方式_postgresql备份

这种方式可以在数据库正在使用的时候进行完整一致的备份&#xff0c;并不阻塞其它用户对数据库的访问。它会产生一个脚本文件&#xff0c;里面包含备份开始时&#xff0c;已创建的各种数据库对象的SQL语句和每个表中的数据。可以使用数据库提供的工具pg_dumpall和pg_dump来进行…

京准:NTP卫星时钟服务器对于DeepSeek安全的重要性

京准&#xff1a;NTP卫星时钟服务器对于DeepSeek安全的重要性 京准&#xff1a;NTP卫星时钟服务器对于DeepSeek安全的重要性 在网络安全领域&#xff0c;分布式拒绝服务&#xff08;DDoS&#xff09;攻击一直是企业和网络服务商面临的重大威胁之一。随着攻击技术的不断演化…

S4 HANA (递延所得税传输)Deferred Tax Transfer - S_AC0_52000644

本文主要介绍在S4 HANA OP中S4 HANA (递延所得税传输)Deferred Tax Transfer - S_AC0_52000644的后台配置及前台操作。具体请参照如下内容&#xff1a; 目录 Deferred Tax Transfer - S_AC0_52000644 1. 后台配置 1.1 Business Transaction Events激活- FIBF 2. 前台操作 …

Redis --- 使用GEO实现经纬度距离计算

什么是GEO&#xff1f; Spring Boot 项目中可以通过 Spring Data Redis 来使用 Redis GEO 功能&#xff0c;主要通过 RedisTemplate 和 GeoOperations 接口来操作地理位置数据。 Service public class GeoService {Autowiredprivate RedisTemplate<String, Object> red…

【中间件】 Kafka

1.先导知识&#xff1a; 消息队列MQ(Message Queue): 将需要传输的数据临时(设置有效期)存放在队列中,进行存取消息消息队列中间件&#xff1a; 用来存储消息的中间件(组件) 2.消息队列的应用场景 异步处理 为什么要使用消息队列&#xff1f; 比较耗时的操作放在其他系统中…

android 打包AAR-引入资源layout-安卓封包

Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_cyberwin_devicescanner);mListView (ListView) this.findViewById(R.id.result);mListView.setAdapter(mListAdapter);

问卷数据分析|SPSS之分类变量描述性统计

1.点击分析--描述统计--频率 2. 选中分类变量&#xff0c;点击中间箭头 3.图表选中条形图&#xff0c;图表值选择百分比&#xff0c;选择确定 4.这里显示出了描述性统计的结果 5.下面就是图形&#xff0c;但SPSS画的图形都不是很好啊看&#xff0c;建议用其他软件画图&#xff…

【Gitlab】虚拟机硬盘文件丢失,通过xx-flat.vmdk恢复方法

前言 由于近期过年回家&#xff0c;为了用电安全直接手动关闭了所有的电源&#xff0c;导致年后回来商上电开机后exsi上的虚拟机出现了问题。显示我的gitlab虚拟机异常。 恢复 开机之后虚拟机异常&#xff0c;通过磁盘浏览发现gitlab服务器下面的虚拟机磁盘文件只有一个xxx-f…