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 {// 体现单例与多例的区别@Testpublic 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@Testpublic void test2() {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-bean.xml");InstanceFactory instanceFactory = (InstanceFactory) applicationContext.getBean("instanceFactory");}// BeanFactory会初始化bean对象,但会根据不同的实现子类采取不同的初始化方式// 默认情况下bean的初始化,单例模式立马会执行,但是此时XmlBeanFactory作为子类,单例模式下容器创建,bean依赖没有初始化,只有要获取使用bean对象才进行初始化@Testpublic 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框架,并在日常开发中取                                                                 

                                                                 

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

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

相关文章

RK3588平台开发系列讲解(AI 篇)RKNN-Toolkit2 API 介绍

文章目录 一、RKNN 初始化及对象释放二、RKNN 模型配置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要讲解 RKNN-Toolkit2 API 详细说明。 一、RKNN 初始化及对象释放 在使用 RKNN Toolkit2 的所有 API 接口时,都需要先调用 RKNN()方法初始化 RKNN 对象,…

STM32 串口复习

按数据通信方式分类&#xff1a; 串行通信&#xff1a;数据逐位按顺序依次传输。传输速率较低&#xff0c;抗干扰能力较强&#xff0c;通信距离较长&#xff0c;I/O资源占用较少&#xff0c;成本较低。并行通信&#xff1a;数据各位通过多条线同时传输。 按数据传输方向分类&…

Flink源码之StreamTask启动流程

每个ExecutionVertex分配Slot后&#xff0c;JobMaster就会向Slot所在的TaskExecutor提交RPC请求执行Task&#xff0c;接口为TaskExecutorGateway::submitTask CompletableFuture<Acknowledge> submitTask(TaskDeploymentDescriptor tdd, JobMasterId jobMasterId, RpcTi…

常见指令以及权限理解

常见指令以及权限理解 命令格式&#xff1a; command [-options] parameter1 parameter1 命令 选项 参数1 参数2 1.command为命令名称&#xff0c;例如变化目录的cd等 2.中括号[ ]实际在命令中是不存在的&#xff0c;这个中括号代表可选&#xff0c;通常选项前面会添加一个符号…

AI 绘画Stable Diffusion 研究(十二)SD数字人制作工具SadTlaker插件安装教程

免责声明: 本案例所用安装包免费提供&#xff0c;无任何盈利目的。 大家好&#xff0c;我是风雨无阻。 想必大家经常看到&#xff0c;无论是在产品营销还是品牌推广时&#xff0c;很多人经常以数字人的方式来为自己创造财富。而市面上的数字人收费都比较昂贵&#xff0c;少则几…

stm32单片机开关输入控制蜂鸣器参考代码(附PROTEUS电路图)

说明&#xff1a;这个buzzer的额定电压需要改为3V&#xff0c;否则不会叫&#xff0c;源代码几乎是完全一样的 //gpio.c文件 /* USER CODE BEGIN Header */ /********************************************************************************* file gpio.c* brief Thi…

【华为认证数通高级证书实验-分享篇2】

实验拓扑 注&#xff1a;代码块为各交换机路由器中的配置命令 配置拓扑文件 实验要求 实现全网通 实验配置 SW3 [SW3]v b 10 20 [SW3]int e0/0/1 [SW3-Ethernet0/0/1]po link-t a [SW3-Ethernet0/0/1]po de v 10 [SW3-Ethernet0/0/1]int e0/0/2 [SW3-Ethernet0/0/2]po li…

table 根据窗口缩放,自适应

element-plus中&#xff0c;直接应用在页面样式上&#xff0c; ::v-deep .el-table{width: 100%; } ::v-deep .el-table__header-wrapper table,::v-deep .el-table__body-wrapper table{width: 100% !important; } ::v-deep .el-table__body,::v-deep .el-table__footer,::v-d…

金融语言模型:FinGPT

项目简介 FinGPT是一个开源的金融语言模型&#xff08;LLMs&#xff09;&#xff0c;由FinNLP项目提供。这个项目让对金融领域的自然语言处理&#xff08;NLP&#xff09;感兴趣的人们有了一个可以自由尝试的平台&#xff0c;并提供了一个与专有模型相比更容易获取的金融数据。…

我能“C”——数据的存储

目录 1. 数据类型介绍 1.1 类型的基本归类&#xff1a; 2. 整形在内存中的存储 2.1 原码、反码、补码 2.2 大小端介绍 2.3 练习 3. 浮点型在内存中的存储 3.1 一个例子 3.2 浮点数存储规则 1. 数据类型介绍 char // 字符数据类型 short // 短整…

学习笔记230818---对于promise失败状态处理的重要性

问题描述&#xff1a; 在项目中经常会出现如上的问题&#xff0c;这是因为&#xff0c;用promise封装的接口或第三方组件方法&#xff0c;如果只对成功的状态做处理&#xff0c;就会造成页面出错&#xff0c;报error。 解决方法 then()的末尾加上.catch(()>{})对失败的状态…

matlab 点云最小二乘拟合空间直线(方法一)

目录 一、算法原理1、空间直线2、最小二乘法拟合二、代码实现三、结果展示四、可视化参考本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、空间直线 x

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,数组)四(116)

需求&#xff1a;&#xff1a;前端根据后端的返回数据&#xff1a;画统计图&#xff1b; 1.动态获取地域数据以及数据中的平均值&#xff0c;按照平均值降序排序&#xff1b; 说明&#xff1a; X轴是动态的&#xff0c;有对应区域数据则展示&#xff1b; X轴 区域数据降序排序…

【NetCore】09-中间件

文章目录 中间件&#xff1a;掌控请求处理过程的关键1. 中间件1.1 中间件工作原理1.2 中间件核心对象 2.异常处理中间件:区分真异常和逻辑异常2.1 处理异常的方式2.1.1 日常错误处理--定义错误页的方法2.1.2 使用代理方法处理异常2.1.3 异常过滤器 IExceptionFilter2.1.4 特性过…

2023国赛数学建模思路 - 案例:ID3-决策树分类算法

文章目录 0 赛题思路1 算法介绍2 FP树表示法3 构建FP树4 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模…

图数据库_Neo4j学习cypher语言_常用函数_关系函数_字符串函数_聚合函数_数据库备份_数据库恢复---Neo4j图数据库工作笔记0008

然后再来看一些常用函数,和字符串函数,这里举个例子,然后其他的 类似 可以看到substring字符串截取函数 可以看到截取成功 聚合函数 这里用了一个count(n) 统计函数,可以看到效果 关系函数,我们用过就是id(r) 可以取出对应的r的id来这样..

【不带权重的TOPSIS模型详解】——数学建模

目录索引 定义&#xff1a;问题引入&#xff1a;不合理之处&#xff1a;进行修改&#xff1a; 指标分类&#xff1a;指标正向化&#xff1a;极小型指标正向化公式&#xff1a;中间型指标正向化公式&#xff1a;区间型指标正向化公式&#xff1a; 标准化处理(消去单位)&#xff…

【应用笔记】使用 CW32 实现电池备份(VBAT)功能

前言 电池备份&#xff08;VBAT&#xff09;功能的实现方法&#xff0c;一般是使用 MCU 自带的 VBAT 引脚&#xff0c;通过在该引脚连接钮扣电池&#xff0c;当系统电源因故掉电时&#xff0c;保持 MCU 内部备份寄存器内容和 RTC 时间信息不会丢失。 本文档介绍了如何基于 C…

PHP8的正则表达式-PHP8知识详解

在网页程序的时候&#xff0c;经常会有查找符合某些复杂规则的字符串的需求。正则表达式就是描述这些规则的工具。 正则表达式是把文本或者字符串按照一定的规范或模型表示的方法&#xff0c;经常用于文本的匹配操作。 例如&#xff1a;我们在填写手机号码的时候&#xff0c;…

java-JVM 类加载机制

JVM 类加载机制 JVM 类加载机制分为五个部分&#xff1a;加载&#xff0c;验证&#xff0c;准备&#xff0c;解析&#xff0c;初始化&#xff0c;下面我们就分别来看一下这五个过程。 1.1. 加载 加载是类加载过程中的一个阶段&#xff0c;这个阶段会在内存中生成一个代表这…