Spring中JavaBean的生命周期及模式

                                  ( 本篇文章大部分讲述了是底层知识,理念及原理 ) 

     ( 如果只想了解,看我标记的重点即可,如果想明白其中原理,请耐心看完,对你大有受益 )

                                                                    

目录

一、简介

( 1 ) 是什么

( 2 ) 背景概述

( 3 ) 作用

二、生命周期

 2.1 讲述

2.2 相关内容

 1) . BeanDefinitionReader

 2) . BeanDefinition

 3) . BeanFactoryPostProcessor

 4) . BeanFactory

 5) . Aware

三、模式

3.1 概述

 单例模式

 多例模式

3.2 演示

给我们带来什么收获


一、简介

( 1 ) 是什么

在Spring框架中,JavaBean的背景可以追溯到Java语言的发展和面向对象编程的原则。JavaBean作为一种特定的编程规范和约定,被引入到Spring框架中,以实现更加灵活和可扩展的开发方式。

在Spring框架中,JavaBean是一个普通的Java类,遵循一些特定的命名和属性规范。一个JavaBean类必须具备以下特征:

  • 1. 私有的成员变量:JavaBean类中的属性通常是私有的,以保护数据,同时提供公共的getter和setter方法来访问和修改属性的值。
  • 2. 无参构造方法:JavaByouean类必须提供一个无参构造方法,用于实例化该类的对象。
  • 3. 可序列化:JavaBean类可以实现Serializable接口,以便在网络传输或持久化时能够将对象转换为字节流。这样,在分布式环境下,可以方便地传输JavaBean对象。

JavaBean在Spring框架中扮演了重要的角色,具有以下优点:

  • 1. 封装数据:JavaBean通过私有属性和公共的getter和setter方法提供对数据的封装,遵循面向对象的封装原则,提高了程序的安全性和可维护性。
  • 2. 兼容性:JavaBean对象可以与其他Spring组件无缝集成,如IoC容器、数据绑定、AOP等。通过JavaBean,可以将业务逻辑和数据操作解耦,增加了代码的灵活性和可扩展性
  • 3. 可重用性:JavaBean可以在不同的应用程序中被重复使用,无需重新编写逻辑。这种可重用性可以大大提高开发效率,减少代码冗余
  • 4. 数据绑定:Spring框架提供了数据绑定功能,可以通过JavaBean将请求参数直接绑定到对象的属性上,简化了数据处理的过程
  • 5. 持久化:JavaBean类可以通过持久化技术(如Hibernate、JPA等)将对象保存到数据库中,实现数据的持久化存储和检索

综上所述,学习JavaBean对于使用Spring框架进行Java开发是非常重要的。它可以帮助我们实现代码的模块化、封装和重用,提高开发效率和代码质量,同时也符合面向对象的设计原则。

( 2 ) 背景概述

  • 面向对象编程:Java是一种面向对象的编程语言,强调通过封装、继承和多态等特性来建立可维护和可扩展软件系统。JavaBean作为一种符合面向对象原则的编程风格,鼓励将数据和行为封装到独立的对象中。

  • 反射与可扩展性:Java的反射机制提供了运行时动态获取类和对象信息的能力,这为JavaBean的创建和操作提供了基础。通过反射,Spring框架可以在运行时实例化JavaBean并设置属性,从而实现解耦和可扩展的编程模型

  • Inversion of Control(IoC):IoC是Spring框架的核心概念之一,它通过将对象的创建和依赖注入的控制权交给框架来实现松耦合。JavaBean的使用正是为了支持IoC,通过约定和配置,Spring框架可以自动地管理和协调JavaBean对象的创建和依赖注入

  • 数据绑定和数据访问:Spring框架提供了强大的数据绑定和数据访问的功能,可以通过JavaBean来实现请求参数与对象属性的自动绑定,并将JavaBean与数据库或其他数据源连接起来。这样可以简化开发过程,提高代码的可读性和可维护性

  •  AOP支持:JavaBean作为Spring框架中的组件,可以非常方便地与AOP(面向切面编程)进行集成,实现横切关注点的解耦。通过对JavaBean对象的增强,可以实现事务管理、日志记录、安全验证等共享的横切功能

综上所述,JavaBean在Spring框架中的背景是基于Java语言的面向对象编程原则,结合反射、IoC和AOP等技术的应用。JavaBean的引入使得Spring框架更加灵活、可扩展,并提供了一种符合规范的对象编程模型,用于简化开发过程和管理对象的生命周期

( 3 ) 作用

在Spring框架中,JavaBean是指符合特定规范的普通Java类,它起到了组件的角色。JavaBean在Spring中充当了以下重要的角色和作用: 

  • 组件化:JavaBean作为Spring框架中的组件,可以被容器管理和维护。通过将JavaBean注册到Spring的IoC容器中,可以实现对其生命周期的控制,包括创建、初始化、销毁等。

  • 依赖注入(Dependency Injection):JavaBean通过依赖注入实现对象之间的松耦合关系。在Spring中,通过配置信息或注解,容器可以自动将依赖注入到JavaBean中,避免了硬编码和耦合的问题,提高了代码的可测试性和可维护性。

  • 数据绑定:JavaBean可以作为数据模型,通过与Spring框架提供的数据绑定功能,将请求参数直接绑定到JavaBean的属性上。这样可以非常方便地处理用户提交的表单数据、进行数据验证和类型转换等操作。

  • AOP支持:JavaBean可以和AOP无缝集成,通过为JavaBean添加切面,可以实现横切关注点的解耦。例如,在JavaBean的方法上添加事务管理切面,实现对事务的控制,而JavaBean无需关心具体的事务管理代码。

  • 序列化与持久化:JavaBean可以通过实现Serializable接口,使得它们的实例可以被序列化为字节流,从而实现网络传输和持久化存储。在Spring中,通过JavaBean的持久化技术(如Hibernate、JPA等),可以将JavaBean的状态保存到数据库中。

  • 配置管理:JavaBean可以通过Spring提供的配置机制(如XML配置、注解配置等),在应用程序启动时进行加载和初始化,Spring容器根据配置信息创建相应的JavaBean对象。这种方式使得应用程序的配置更加灵活和可管理。

总的来说,JavaBean在Spring框架中扮演了重要的角色,它不仅是一个普通的Java类,还具有组件化、依赖注入、数据绑定、AOP支持等功能。学习和使用JavaBean,可以帮助开发人员更好地理解和使用Spring框架,从而提高开发效率和代码质量。

二、生命周期

 2.1 讲述

在Spring中,JavaBean的生命周期涉及到以下类和接口:

  • 1. 实例化:在这个阶段,Spring使用反射机制创建JavaBean的实例。主要使用的类是Class类,该类提供了获取类的构造方法的方法。在配置文件中,可以使用<bean>标签来配置JavaBean的实例化方式,包括使用默认构造方法实例化、使用静态工厂方法实例化或使用实例工厂方法实例化。
  • 2. 属性注入:在实例化完成后,Spring会将属性值注入到JavaBean中。这个阶段使用到的类有BeanWrapper、BeanDefinition和PropertyValues。BeanWrapper是一个用于包装JavaBean的类,它可以通过反射设置JavaBean的属性值。BeanDefinition是一个用于描述JavaBean的元数据的类,它包含了JavaBean的类名、属性值等信息PropertyValues是一个用于保存JavaBean属性值的类,它可以通过键值对的方式保存属性值。在配置文件中,可以使用<property>标签或通过注解来配置JavaBean的属性注入方式。
  • 3. 初始化:在属性注入完成后,Spring会调用JavaBean的初始化方法。这个阶段可以通过实现InitializingBean接口或在配置文件中指定初始化方法来实现。InitializingBean接口中有一个afterPropertiesSet()方法,可以在该方法中进行初始化操作。另外,还可以通过在配置文件中使用init-method属性来指定初始化方法。在初始化方法中,可以进行一些对象的初始化操作,如初始化连接池、加载配置文件等。
  • 4. 使用:在初始化完成后,JavaBean可以被其他组件或对象使用了。这个阶段主要是调用JavaBean的方法进行业务逻辑处理
  • 5. 销毁:当Spring容器关闭时,会调用JavaBean的销毁方法进行资源的释放。这个阶段可以通过实现DisposableBean接口或在配置文件中指定销毁方法来实现。DisposableBean接口中有一个destroy()方法,可以在该方法中进行资源释放操作。另外,还可以通过在配置文件中使用destroy-method属性来指定销毁方法。在销毁方法中,可以进行一些资源的释放操作,如关闭连接、释放内存等。

需要注意的是,JavaBean的生命周期是由Spring容器管理的,所以只有在Spring容器中才会进行相应的生命周期操作。如果使用纯Java方式创建的对象,则不会经过Spring的生命周期管理。在配置文件中,可以使用XML配置方式或注解方式来描述JavaBean的生命周期。XML配置方式可以通过<bean>标签来配置JavaBean的属性值、初始化方法和销毁方法。注解方式可以通过在JavaBean类上使用相应的注解来描述初始化方法和销毁方法,如@PostConstruct和@PreDestroy注解。

2.2 相关内容

 1) . BeanDefinitionReader

在Spring中,BeanDefinitionReader是用于读取并解析配置文件的类,它在JavaBean的生命周期中起着重要的作用。

在JavaBean的生命周期中,BeanDefinitionReader主要用于实例化和属性注入阶段。它会读取配置文件中的<bean>标签,并解析其中的属性值、初始化方法和销毁方法等信息。通过解析配置文件,BeanDefinitionReader可以获取到JavaBean的类名、属性值、初始化方法和销毁方法等元数据。

在实例化阶段,BeanDefinitionReader会根据配置文件中的信息使用反射机制创建JavaBean的实例。它会根据配置文件中的<bean>标签中的class属性获取到JavaBean的类名,并使用反射机制创建JavaBean的实例。

在属性注入阶段,BeanDefinitionReader会根据配置文件中的<property>标签获取到JavaBean的属性值,并使用反射机制将属性值注入到JavaBean中。它会根据配置文件中的<property>标签中的name属性获取到属性名,然后根据name属性获取到对应的属性值,并使用反射机制将属性值注入到JavaBean中。

除了实例化和属性注入阶段,BeanDefinitionReader还可以在其他阶段发挥作用。例如,在初始化阶段,BeanDefinitionReader可以读取配置文件中的init-method属性,并将其作为初始化方法进行调用。在销毁阶段,BeanDefinitionReader可以读取配置文件中的destroy-method属性,并将其作为销毁方法进行调用。

总之,BeanDefinitionReader在JavaBean的生命周期中起着解析和读取配置文件的作用,它能够获取到JavaBean的元数据,并根据配置文件中的信息进行实例化、属性注入、初始化和销毁等操作。

 2) . BeanDefinition

BeanDefinition是Spring框架中的一个重要概念,它用于描述和定义一个Bean的信息。

具体来说,BeanDefinition的作用主要有以下几个方面:

  • 1. 定义Bean的属性:BeanDefinition定义了一个Bean的属性,包括Bean的类名、作用域、是否懒加载、依赖关系等。通过BeanDefinition,可以对Bean的属性进行配置和管理。
  • 2. 描述Bean的依赖关系:BeanDefinition描述了Bean与其他Bean之间的依赖关系。它可以指定Bean所依赖的其他Bean,以及依赖的方式(如通过构造函数注入、setter方法注入等)。通过BeanDefinition,可以实现Bean之间的依赖注入。
  • 3. 定义Bean的初始化和销毁方法:BeanDefinition可以定义Bean的初始化方法和销毁方法。它可以指定Bean在实例化之后需要执行的初始化方法,以及在销毁之前需要执行的销毁方法。通过BeanDefinition,可以实现对Bean生命周期的管理。
  • 4. 扩展Bean的功能:通过BeanDefinition,可以对Bean的定义进行扩展,实现自定义的功能。可以在BeanDefinition中添加AOP切面、事务管理等功能,从而实现对Bean的增强。
  • 5. 灵活配置Bean的定义:BeanDefinition提供了灵活的配置方式,可以通过XML配置文件、注解或编程的方式来定义Bean。可以根据需要,选择合适的方式来配置Bean的定义。

总之,BeanDefinition是Spring框架中用于描述和定义Bean的信息的重要概念。它定义了Bean的属性、依赖关系、初始化和销毁方法等信息,可以实现对Bean的配置和管理。通过BeanDefinition,可以实现灵活的Bean配置和扩展,从而实现对Bean的定制化功能。

 3) . BeanFactoryPostProcessor

BeanFactoryPostProcessor是Spring框架中的一个扩展接口,它可以在Spring容器实例化Bean之后,对Bean的定义进行修改或扩展。

具体来说,BeanFactoryPostProcessor的作用主要有以下几个方面:

  • 1. 修改Bean的定义:通过实现BeanFactoryPostProcessor接口,可以在Spring容器实例化Bean之前,对Bean的定义进行修改。可以添加、删除或修改Bean的属性值、作用域、依赖关系等。这样可以在不修改源代码的情况下,对Bean的定义进行动态调整。
  • 2. 扩展Bean的定义:通过实现BeanFactoryPostProcessor接口,可以在Spring容器实例化Bean之前,对Bean的定义进行扩展。可以添加新的Bean定义,或者通过修改Bean的定义来实现自定义的扩展功能。例如,可以在Bean的定义中添加AOP切面、事务管理等功能。
  • 3. 配置Bean的属性值:通过实现BeanFactoryPostProcessor接口,可以在Spring容器实例化Bean之前,对Bean的属性值进行配置。可以根据需要,动态地设置Bean的属性值,从而实现更灵活的配置。
  • 4. 解析和处理Bean的定义:BeanFactoryPostProcessor接口还可以用于解析和处理Bean的定义。可以根据需要,对Bean的定义进行解析和处理,以实现特定的逻辑。例如,可以根据Bean的定义生成其他相关的Bean定义,或者根据Bean的定义进行一些逻辑判断和处理。

需要注意的是,BeanFactoryPostProcessor是在Spring容器实例化Bean之后,对Bean的定义进行修改或扩展的。它与BeanPostProcessor接口的区别在于,BeanFactoryPostProcessor是在Bean的定义阶段进行操作,而BeanPostProcessor是在Bean的实例化和初始化阶段进行操作。因此,BeanFactoryPostProcessor可以对Bean的定义进行修改,而BeanPostProcessor只能对Bean的实例进行操作。

 4) . BeanFactory

BeanFactory是Spring框架中的核心接口之一,它是用于管理和获取Bean实例的工厂。

具体来说,BeanFactory的作用主要有以下几个方面:

  • 1. 实例化Bean:BeanFactory负责根据配置文件或注解等方式,实例化JavaBean。它会根据配置文件中的<bean>标签或注解中的配置信息,使用反射机制创建JavaBean的实例。通过BeanFactory,可以方便地创建和获取各种类型的Bean实例。
  • 2. 管理Bean的生命周期:BeanFactory管理着Bean的生命周期。它会在需要时创建Bean的实例,并在不需要时销毁Bean的实例。通过BeanFactory,可以控制Bean的创建、初始化和销毁等过程,实现对Bean的灵活管理。
  • 3. 注入依赖关系:BeanFactory负责将Bean之间的依赖关系注入到Bean实例中。它会根据配置文件中的<property>标签或注解中的依赖关系,将依赖的Bean注入到目标Bean中。通过BeanFactory,可以实现Bean之间的依赖注入,从而实现松耦合的设计。
  • 4. 提供Bean的访问接口:BeanFactory提供了访问Bean的接口,可以方便地获取已经实例化的Bean。通过BeanFactory,可以根据Bean的名称或类型,获取到对应的Bean实例。这样可以方便地在应用程序中使用Bean,实现各种功能。

总之,BeanFactory是Spring框架中用于管理和获取Bean实例的核心接口。它负责实例化Bean、管理Bean的生命周期、注入依赖关系和提供Bean的访问接口等功能,是Spring框架中实现IoC(控制反转)和DI(依赖注入)的重要组成部分。

 5) . Aware

Aware是Spring框架中的一组接口,用于在Bean实例化过程中向Bean注入特定的资源或回调接口。

具体来说,Aware接口主要有以下几个作用:

  • 1. 提供对Spring容器的访问:通过实现ApplicationContextAware接口,Bean可以获取对Spring容器的引用。这样可以在Bean中直接访问Spring容器的各种功能,如获取其他Bean、获取环境变量等。
  • 2. 提供对BeanFactory的访问:通过实现BeanFactoryAware接口,Bean可以获取对BeanFactory的引用。这样可以在Bean中直接访问BeanFactory的各种功能,如获取Bean的定义、获取Bean的属性等。
  • 3. 提供对Bean的名称的访问:通过实现BeanNameAware接口,Bean可以获取自己在Spring容器中的名称。这样可以在Bean中获取自己的名称,做一些特定的处理。
  • 4. 提供对资源的访问:通过实现ResourceLoaderAware接口,Bean可以获取对资源加载器的引用。这样可以在Bean中直接加载资源,如读取配置文件、访问文件等。
  • 5. 提供对消息源的访问:通过实现MessageSourceAware接口,Bean可以获取对消息源的引用。这样可以在Bean中直接访问消息源,实现国际化和本地化的功能。

通过实现这些Aware接口,Bean可以获取到Spring容器的相关资源或回调接口,从而实现对这些资源的访问或使用。这样可以在Bean中更方便地实现一些特定的功能,提高系统的灵活性和可扩展性。

三、模式

3.1 概述

Spring是一个综合性的开发框,如果不进行配置,它默认是单例模式

但它也可以配置为多例模式。

 单例模式

Spring使用单例模式的主要优点和好处包括:

  • 1. 节省资源:单例模式可以确保在整个应用程序中只有一个实例存在,节省了系统资源的开销。每次请求都返回同一个实例,避免了重复创建对象的开销。
  • 2. 提高性能:由于单例模式只创建一个实例,避免了频繁的创建和销毁对象的开销,从而提高了系统的性能。
  • 3. 避免竞争条件:在多线程环境下,使用单例模式可以避免多个线程同时访问和修改对象的状态,从而避免了竞争条件和数据不一致的问题。
  • 4. 统一管理和协调资源:单例模式可以统一管理和协调系统中的共享资源,确保资源的正确使用和释放,避免资源泄漏和浪费。
  • 5. 提供全局访问点:单例模式可以提供一个全局的访问点,方便其他对象或模块通过该访问点来获取实例,简化了对象的使用和调用。
  • 6. 简化配置和管理:在Spring框架中,将Bean定义为单例模式可以简化配置和管理,只需要在配置文件或注解中声明为单例即可,Spring容器负责创建和管理单例对象。

总的来说,Spring使用单例模式的优点包括节省资源、提高性能、避免竞争条件、统一管理和协调资源、提供全局访问点以及简化配置和管理。这些优点使得Spring在处理大规模应用和高并发环境下表现出色,并且提供了更好的可扩展性和可维护性。

在使用单例模式时,可能会存在以下两个缺点:

  • 1. 状态共享和线程安全问题:由于单例模式只创建一个实例,多个线程共享该实例,可能会导致状态共享和线程安全问题。如果多个线程同时访问和修改单例对象的状态,可能会导致数据不一致的问题。为了解决这个问题,需要在代码中进行适当的同步控制,增加了开发和维护的复杂度。
  • 2. 依赖关系和耦合度高:单例模式会导致对象之间的依赖关系和耦合度较高。由于单例对象在整个系统中都是可见的,其他对象可能会直接依赖于单例对象,导致对象之间的紧耦合。这样一来,当需要对单例对象进行修改或替换时,可能会涉及到多个对象的修改,增加了系统的维护成本和风险。

需要注意的是,这些缺点并不是单例模式本身的问题,而是在使用单例模式时可能会出现的问题。通过合理的设计和使用,可以减轻这些问题的影响。比如,可以通过尽量避免共享状态、合理控制同步访问、使用线程安全的方式创建单例对象等方式来解决状态共享和线程安全问题;同时,可以通过依赖注入、面向接口编程等方式降低对象之间的耦合度。

总结的说 : 单列模式可以节约内存,提高性能、但是会有变量污染,提高风险。

 多例模式

在Spring框架中,多例模式(Prototype Pattern)是指每次获取对象实例时都会创建一个新的实例,相比于单例模式,多例模式具有以下优点和好处:

  • 1. 灵活性:多例模式可以根据需求创建多个实例,每个实例可以有不同的状态和属性,提供了更大的灵活性和定制性。
  • 2. 避免共享状态:多例模式每次创建新的实例,避免了多个对象之间共享状态的问题。每个实例都是独立的,互不影响。
  • 3. 高并发性能:在高并发环境下,多例模式可以减少线程竞争,提高系统的并发性能。每个线程获取到的都是独立的实例,不会出现资源竞争的情况。
  • 4. 避免单例模式的缺点:单例模式在某些场景下可能会存在线程安全问题、资源占用过多等缺点,而多例模式可以避免这些问题。
  • 5. 降低耦合度:多例模式可以降低对象之间的耦合度,每个对象都是独立的,可以独立创建和销毁,不会产生过多的依赖关系。
  • 6. 提供灵活的生命周期管理:多例模式可以通过Spring容器的生命周期管理功能来管理实例的创建和销毁,提供了更灵活的生命周期管理方式。

需要注意的是,多例模式也存在一些潜在的问题,比如对象的创建和销毁开销较大,可能会影响系统性能;多例模式可能会导致对象的过度创建,占用过多的系统资源。因此,在使用多例模式时需要根据具体的业务场景和性能需求进行权衡和选择。

在Spring框架中使用多例模式(Prototype Pattern)可能会存在以下缺点:

  • 1. 资源消耗过多:每次获取多例对象时都会创建一个新的实例,这可能会导致系统资源的过度消耗。如果多例对象的创建和销毁过程比较复杂,可能会导致系统性能下降。
  • 2. 难以管理和维护:多例模式创建的实例数量可能会很多,这会增加系统的复杂性和维护成本。如果没有良好的管理和控制机制,可能会导致实例过多、内存泄漏等问题。
  • 3. 难以保证一致性:多例模式创建的实例是相互独立的,每个实例都有自己的状态和属性。这可能会导致系统中存在大量的不一致性,增加了系统的复杂性和调试难度。
  • 4. 不适合共享资源:多例模式每次创建新的实例,不适合用于共享资源的场景。如果多个对象需要共享某些资源,可能需要额外的处理和同步机制。

需要根据具体的业务场景和性能需求来选择使用多例模式。在一些需要灵活性和定制性较高的场景下,多例模式可以提供更大的灵活性。但同时也需要注意管理和控制多例对象的数量,避免资源的过度消耗。

总结的说: 多列模式没有变量污染,没有风险,但是会非常消耗资源及内存。

3.2 演示

创建 ParamAction 类

package com.CloudJun.bean;

import java.util.List;

/**
 * @author CloudJun
 * @create  2023-08-18 13:44
 */
public class ParamAction {
	private int age;
	private String name;
	private List<String> hobby;
	private int num = 1;
	// private UserBiz userBiz = new UserBizImpl1();

	public ParamAction() {
		super();
	}

	public ParamAction(int age, String name, List<String> hobby) {
		super();
		this.age = age;
		this.name = name;
		this.hobby = hobby;
	}

	public void execute() {
		// userBiz.upload();
		// userBiz = new UserBizImpl2();
		System.out.println("this.num=" + this.num++);
		System.out.println(this.name);
		System.out.println(this.age);
		System.out.println(this.hobby);
	}
}

创建 InstanceFactory 类

package com.CloudJun.bean;

/**
 * @author CloudJun
 * @create  2023-08-18 13:42
 */
public class InstanceFactory {
	public void init() {
		System.out.println("初始化方法");
	}

	public void destroy() {
		System.out.println("销毁方法");
	}

	public void service() {
		System.out.println("业务方法");
	}
}

创建配置文件 spring-bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean  class="com.CloudJun.bean.ParamAction" id="paramAction" scope="prototype">
        <constructor-arg name="name" value="三丰"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>抽烟</value>
                <value>烫头</value>
                <value>大保健</value>
            </list>
        </constructor-arg>
    </bean>

    <bean id="instanceFactory" class="com.CloudJun.bean.InstanceFactory"
          scope="singleton" init-method="init" destroy-method="destroy"></bean>



</beans>

创建测试类 Demo2

package com.CloudJun.bean;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

/*
 * spring	bean的生命週期
 * spring	bean的單例多例
 * @author CloudJun
 * @create  2023-08-18 13:44
 *
 */
public class Demo2 {
	// 体现单例与多例的区别
	@Test
	public void test1() {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-bean.xml");
//		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-bean.xml");
		ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
		ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
		// System.out.println(p1==p2);
		p1.execute();
		p2.execute();
		
//		单例时,容器销毁instanceFactory对象也销毁;多例时,容器销毁对象不一定销毁;
		applicationContext.close();
	}

	// 体现单例与多例的初始化的时间点 instanceFactory
	@Test
	public void test2() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-bean.xml");
		InstanceFactory instanceFactory = (InstanceFactory) applicationContext.getBean("instanceFactory");

	}

	// BeanFactory会初始化bean对象,但会根据不同的实现子类采取不同的初始化方式
	// 默认情况下bean的初始化,单例模式立马会执行,但是此时XmlBeanFactory作为子类,单例模式下容器创建,bean依赖没有初始化,只有要获取使用bean对象才进行初始化
	@Test
	public void test3() {
		// ClassPathXmlApplicationContext applicationContext = new
		// ClassPathXmlApplicationContext("/spring-bean.xml");
		Resource resource = new ClassPathResource("/spring-bean.xml");
		BeanFactory beanFactory = new XmlBeanFactory(resource);
		InstanceFactory i1 = (InstanceFactory) beanFactory.getBean("instanceFactory");
		
	}

}

测试Demo2中的test1方法

使用单例模式测试结果

将spring-bean.xml 配置文件中的scope="prototype"修改

为scope="singleton"便是使用多例模式

使用多例模式测试结果

测试Demo2中的test2方法

( 提示: 当内容比较多时,可以在xml配置文件中修改单列或者多列模式继续运行速度测试 ) 

测试Demo2中的test3方法

BeanFactory会初始化bean对象,但会根据不同的实现子类采取不同的初始化方式 

( 提示: 当内容比较多时,可以在xml配置文件中修改单列或者多列模式继续运行速度测试 ) 

给我们带来什么收获

学习Spring框架中的JavaBean对我们有以下收获:

  • 1. 灵活的开发方式:学习使用JavaBean可以帮助我们以一种更加灵活和可扩展的方式进行开发。JavaBean的依赖注入机制可以帮助我们实现松耦合的组件之间的交互,提高代码的可维护性和可测试性。
  • 2. 提高开发效率:Spring框架提供了大量的现成的JavaBean组件,可以在我们的应用程序中直接使用。这些组件包括事务管理、持久化、安全验证等功能,可以节省我们自己编写这些功能代码的时间和精力,提高开发效率。
  • 3. 更好的代码组织和管理:通过将应用程序中的不同功能模块拆分成各个JavaBean组件,可以使代码更具可读性、可维护性和可扩展性。JavaBean也可以作为数据模型,帮助我们将业务逻辑与数据操作分离,使代码更好地符合单一职责原则。
  • 4. 使用Spring提供的功能和特性:学习使用JavaBean可以打开使用Spring框架更多功能和特性的大门。Spring提供了丰富的功能,如AOP、数据绑定、事务管理等,通过合理利用JavaBean,我们可以从中受益,提高应用程序的质量和性能。
  • 5. 探索Java生态系统:JavaBean在Spring框架中的使用是我们进入更广阔Java生态系统的一扇门。Spring是Java生态系统中最流行的框架之一,掌握JavaBean的使用,有助于我们更好地理解和使用其他相关框架和技术。

综上所述,学习Spring框架中的JavaBean可以为我们带来诸多收获,包括灵活的开发方式、提高开发效率、更好的代码组织和管理,以及进一步探索Java生态系统的机会。掌握JavaBean的使用,可以使我们更加熟练地使用Spring框架,并在日常开发中取                                                                 

                                                                 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数组详解

1. 一维数组的创建和初始化 1.1 数组的创建 数组是一组相同类型元素的集合。 数组的创建方式&#xff1a; type_t arr_name [const_n]; //type_t 是指数组的元素类型 //const_n 是一个常量表达式&#xff0c;用来指定数组的大小 数组创建的实例&#xff1a; //代码1 int a…

STM32 F103C8T6学习笔记8:0.96寸单色OLED显示屏显示字符

使用STM32F103 C8T6 驱动0.96寸单色OLED显示屏: OLED显示屏的驱动&#xff0c;在设计开发中OLED显示屏十分常见&#xff0c;因此今日学习一下。一篇文章从程序到显示都讲通。 文章提供源码、原理解释、测试工程下载&#xff0c;测试效果图展示。 目录 OLED驱动原理—IIC通信…

centos7 部署kubernetes(带自动部署脚本)

目录 一、实验规划 1、规划表 2、安装前宿主机检查 1.配置主机名 2.制作ssh免密&#xff08;VM1中执行&#xff09; 3.修改hosts 文件 4. 修改内核相关参数 5.加载模块 6. 清空iptables、关闭防火墙、关闭交换空间、禁用selinux 7. 安装ipvs与时钟同步 8.配置docker的…

【算法挨揍日记】day03——双指针算法_有效三角形的个数、和为s的两个数字

611. 有效三角形的个数 611. 有效三角形的个数https://leetcode.cn/problems/valid-triangle-number/ 题目描述&#xff1a; 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 解题思路&#xff1a; 本题是一个关于三角形是否能成立…

【数仓建设系列之一】什么是数据仓库?

一、什么是数据仓库&#xff1f; 数据仓库(Data Warehouse&#xff0c;简称DW)简单来讲&#xff0c;它是一个存储和管理大量结构化和非结构化数据的存储集合&#xff0c;它以主题为向导&#xff0c;通过整合来自不同数据源下的数据(比如各业务数据&#xff0c;日志文件数据等)…

Azure使用CLI创建VM

使用CLI创建VM之前&#xff0c;确保资源中的IP资源已经释放掉了&#xff0c;避免创建的过程中没有可以利用的公共IP地址打开 cloudshell ,并输入创建CLI的命令如下&#xff0c;-n指定名称&#xff0c;-g指定资源组&#xff0c;image指定镜像&#xff0c;admin-usernam指定用户名…

C++音乐播放系统

C音乐播放系统 音乐的好处c发出声音乐谱与赫兹对照把歌打到c上 学习c的同学们都知道&#xff0c;c是一个一本正经的编程语言&#xff0c;因该没有人用它来做游戏、做病毒、做…做…做音乐播放系统吧&#xff01;&#xff01; 音乐的好处 提升情绪&#xff1a;音乐能够影响我们…

Spring Framework中的Bean生命周期

目录 一.Bean生命周期的简介 1.基本概念 2.Spring生命周期的几大阶段 3.注意点及小结 4.生活案例 5.Spring容器管理JavaBean的初始化过程 二. Bean的单例选择与多例选择 1.单例选择与多例选择的优缺点 1.1单例模式的优点&#xff1a; 1.2单例模式的缺点&#xff1a; 1…

insightface安装过程中提示 Microsoft Visual C++ 14.0 or greater is required.

pip install insightface安装过程中提示 Microsoft Visual C 14.0 or greater is required.Get it with "Microsoft C Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/ 根据提示网站访问官网下载生成工具 打开软件后会自动更新环境&#…

Ceph入门到精通-Aws Iam(user,role,group,policy,resource)架构图和快速入门

-- Aws Iam(identity,user,role,group,policy,resource,)架构图和快速入门. 【官网】&#xff1a;Cloud Computing Services - Amazon Web Services (AWS) 应用场景 aws 云服务运维,devops过程中经常涉及各项服务&#xff0c;权限&#xff0c;角色的处理。 为了更好的使用各项…

leetcode 279. 完全平方数

2023.8.18 与零钱兑换相似&#xff0c;本题属于完全背包问题&#xff1a;完全平方数为物品&#xff0c;整数n为背包。 直接上代码&#xff1a; class Solution { public:int numSquares(int n) {vector<int> dp(n1 , INT_MAX);dp[0] 0;for(int i1; i*i<n; i){for(in…

BIO、NIO和AIO

一.引言 何为IO 涉及计算机核心(CPU和内存)与其他设备间数据迁移的过程&#xff0c;就是I/O。数据输入到计算机内存的过程即输入&#xff0c;反之输出到外部存储&#xff08;比如数据库&#xff0c;文件&#xff0c;远程主机&#xff09;的过程即输出。 I/O 描述了计算机系统…

AMD fTPM RNG的BUG使得Linus Torvalds不满

导读因为在 Ryzen 系统上对内核造成了困扰&#xff0c;Linus Torvalds 最近在邮件列表中表达了对 AMD fTPM 硬件随机数生成器的不满&#xff0c;并提出了禁用该功能的建议。 因为在 Ryzen 系统上对内核造成了困扰&#xff0c;Linus Torvalds 最近在邮件列表中表达了对 AMD fTPM…

原生js获取今天、昨天、近7天的时间(年月日时分秒)

有的时候我们需要将今天,昨天,近7天的时间(年月日时分秒)作为参数传递给后端,如下图: 那怎么生成这些时间呢?如下代码里,在methods里的toDay方法、yesterDay方法、weekDay方法分别用于生成今天、昨天和近7天的时间: <template><div class="box"&…

【校招VIP】测试方案之测试用例分析

考点介绍 测试用例是测试岗面试和工作后的核心&#xff0c;在面试里对测试用例的分析是高频考查点。但是很多同学因为没有真实的商业产品需求&#xff0c;只能简单的看别人的用例学习&#xff0c;导致面试时被一个陌生问题卡住。 比如最简单的用户名密码输入&#xff0c;在商业…

⛳ Docker - Centos 安装配置

目录 ⛳ Docker - Centos 安装配置&#x1f3ed; Docker 安装&#xff1a;&#x1f4e2; 一、安装依赖包&#x1f4ac; 二、添加 Docker 下载源地址&#x1f43e; 三、更新yum缓存&#x1f463; 四、安装Docker&#x1f4bb; 五、启动Docker&#x1f381; 六、查看Docker状态和…

vue3 + antv/x6 实现拖拽侧边栏节点到画布

前篇&#xff1a;vue3ts使用antv/x6 自定义节点 前篇&#xff1a;vue3antv x6自定义节点样式 1、创建侧边栏 用antd的menu来做侧边栏 npm i --save ant-design-vue4.x//入口文件main.js内 import Antd from ant-design-vue; import App from ./App; import ant-design-vue/…

OpenFOAM的fvOptions

采用OpenFoam中的fvOptions /*--------------------------------*- C -*----------------------------------*\ |\\ / F ield | OpenFOAM: The Open Source CFD Toolbox\\ / O peration | Website: https://openfoam.org\\ / A n…

安卓框架中的常见问题汇总

目录 1.安卓操作系统的组件结构图如下 2.问题汇总 1.安卓操作系统的组件结构图如下 2.问题汇总 问题1&#xff1a;安卓框架中的库和应用程序框架之间什么关系&#xff1f; 在安卓系统中&#xff0c;应用程序框架层&#xff08;Application Framework&#xff09;是核心应用程…

ADC静态特性测试

测试环境搭建&#xff1a; 码密度分析法的局限性 更新&#xff1a; MATLAB R2020a之后的版本&#xff0c;更新了函数 “inldnl()”&#xff0c;可以自动计算INL和DNL。具体用法看MATLAB说明文档即可。