当前位置: 首页 > news >正文

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框架,并在日常开发中取                                                                 

                                                                 

相关文章:

Spring中JavaBean的生命周期及模式

( 本篇文章大部分讲述了是底层知识&#xff0c;理念及原理 ) ( 如果只想了解&#xff0c;看我标记的重点即可&#xff0c;如果想明白其中原理&#xff0c;请耐心看完&#xff0c;对你大有受益 ) 目录 一、简介 ( 1 ) 是什么 ( 2 ) 背景概述 ( 3 ) 作用 二、生命周期 2.1 …...

Qt5开发环境-银河麒麟V10ARM平台

目录 前言1.源码下载2.编译安装2.1 安装依赖2.2 编译2.3 遇到的问题2.4 安装 3.编译qtwebengine3.1 安装依赖库3.2 编译3.3 遇到的问题3.4 安装 4.配置开发环境5.测试6.程序无法输入中文的问题总结 前言 近期因参与开发的某个软件需要适配银河麒麟v10arm 平台&#xff0c;于是…...

「Qt」文件读写操作

0、引言 我们知道 C 和 C 都提供了文件读写的类库&#xff0c;不过 Qt 也有一套自己的文件读写操作&#xff1b;本文主要介绍 Qt 中进行文件读写操作的类 —— QFile。 1、QFileDialog 文件对话框 一般的桌面应用程序&#xff0c;当我们想要打开一个文件时&#xff0c;通常会弹…...

0101前期准备-大数据学习

文章目录 1 前言2 配置VMware虚拟机2.1 设置主机名和固定IP2.2 本地系统与Linux系统配置主机名映射2.3 配置虚拟机之间用户的SSH免密互通2.4 安装JDK环境2.5 关闭防火墙和SELinux2.6 更新时区和同步时间2.7 保存虚拟机快照 结语 1 前言 我们从基础的hadoop开始学起&#xff0c;…...

TypeScript教程(四)基本运算符

一、运算符 TypeScript包含以下几种运算符&#xff1a; 1.算术运算符 2.逻辑运算符 3.关系运算符 4.按位运算符 5.赋值运算符 6.三元/条件运算符 7.字符串运算符 8.类型运算符 1.算术运算符 y5 运算符描述例子x 运算结果y 运算结果加法xy275-减法xy-235*乘法xy*2105…...

计算机网络的性能指标

计算机网络的性能指标 1. 速率 速率是指数据在网络中传送的速度&#xff0c;通常用比特率或数据率来表示&#xff0c;单位是b/s&#xff0c;或bit/s&#xff0c;即比特每秒&#xff0c;或者bps(bit per second)。 速率单位&#xff1a;1 Ybps 10^24 bps(尧), 1 Zbps 10^21…...

BBS项目day04 文章详情页、点赞点菜、评论功能

一、路由 from django.contrib import admin from django.urls import path, re_path from app01 import views from django.views.static import serve from django.conf import settingsurlpatterns [path(admin/, admin.site.urls),# 注册path(register/, views.register)…...

el-table分页后序号连续的两种方法

实现效果&#xff1a; 第一页排序到10&#xff0c;第二页的排序应从11开始 实现方法一&#xff1a; 在el-table的序号列中使用template定义 <el-table><el-table-columnmin-width"10%"label"序号"><template slot-scope"scope"…...

Nginx反向代理技巧

跨域 作为一个前端开发者来说不可避免的问题就是跨域&#xff0c;那什么是跨域呢&#xff1f; 跨域&#xff1a;指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的&#xff0c;是浏览器对javascript施加的安全限制。浏览器的同源策略是指协议&#xff0c;域名…...

kafka--kafka的基本概念-副本概念replica

三、kafka的基本概念-副本概念replica Broker 表示实际的物理机器节点 Broker1中的绿色P1表示主分片Broker2中的蓝色P1表示副本分片&#xff0c;其余类似&#xff0c;就是主从的概念&#xff0c;如果一个Broker挂掉了&#xff0c;还有其它的节点来保证数据的完整性 P可以看做分…...

css伪元素实现li列表圆点相连+锚点跳转悬浮窗实现

实现效果&#xff1a; html代码&#xff1a; <div class"sidenav"><ul class"nav-text progressbar"><!-- data-target的值对应要跳转的模块的id --><li data-target"module1"><div class"text">锚点…...

IronPDF for .NET Crack

IronPDF for .NET Crack ronPDF现在将等待HTML元素加载后再进行渲染。 IronPDF现在将等待字体加载后再进行渲染。 添加了在绘制文本时指定旋转的功能。 添加了在保存为PDFA时指定自定义颜色配置文件的功能。 IronPDF for.NET允许开发人员在C#、F#和VB.NET for.NET Core和.NET F…...

【C++进阶】继承、多态的详解(多态篇)

【C进阶】继承、多态的详解&#xff08;多态篇&#xff09; 目录 【C进阶】继承、多态的详解&#xff08;多态篇&#xff09;多态的概念多态的定义及实现多态的构成条件&#xff08;重点&#xff09;虚函数虚函数的重写&#xff08;覆盖、一种接口继承&#xff09;C11 override…...

excel快速选择数据、选择性粘贴、冻结单元格

一、如何快速选择数据 在excel中&#xff0c;希望选择全部数据&#xff0c;通常使用鼠标选择数据然后往下拉&#xff0c;当数据很多时&#xff0c;也可单击单元格使用ctrl A选中全部数据&#xff0c;此外&#xff0c;具体介绍另一种方法。 操作&#xff1a;ctrl shift 方向…...

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

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

Vue2-配置脚手架、分析脚手架、render函数、ref属性、props配置项、mixin配置项、scoped样式、插件

&#x1f954;:总有一段付出了没有回报的日子 是在扎根 更多Vue知识请点击——Vue.js VUE2-Day6 配置脚手架脚手架结构render函数vue.js与vue.runtime.xxx.js的区别引入render函数为什么要引入残缺的vue呢&#xff1f; 脚手架默认配置ref属性props配置项传递数据接收数据注意点…...

VS2015项目中,MFC内存中调用DLL函数(VC6生成的示例DLL)

本例主要讲一下&#xff0c;用VC6如何生成DLL&#xff0c;用工具WinHex取得DLL全部内容&#xff0c;VC2015项目加载内存中的DLL函数&#xff0c;并调用函数的示例。 本例中的示例代码下载&#xff0c;点击可以下载 一、VC6.0生成示例DLL项目 1.新建项目&#xff0c;…...

人流目标跟踪pyqt界面_v5_deepsort

直接上效果图 代码仓库和视频演示b站视频006期&#xff1a; 到此一游7758258的个人空间-到此一游7758258个人主页-哔哩哔哩视频 代码展示&#xff1a; YOLOv5 DeepSORT介绍 YOLOv5 DeepSORT是一个结合了YOLOv5和DeepSORT算法的目标检测与多目标跟踪系统。让我为您详细解释一…...

angular 子组件ngOnChanges监听@input传入的输入属性

在进入主题之前&#xff0c;先了解一下angular的生命周期。 生命周期 钩子分类 指令与组件共有的钩子 ngOnChangesngOnInitngDoCheckngOnDestroy 组件特有的钩子 ngAfterContentInitngAfterContentCheckedngAfterViewInitngAfterViewChecked 生命周期钩子的作用及调用顺序 …...

移植PeerTalk开源库IOS的USB通信监听服务到QT生成的FFmpeg工程

1.添加生成的PeerTalk库 下图选中部分为FFmpeg依赖库 将USB通信服务的m与h文件添加到工程 因为OC文件使用了弱指针,所以要启用弱指针支持 因为FFmpeg拉流动用到本地网络,所以要在plist文件中启动本地网络使用 设置PeerTalk为嵌入模式 设置Runpath Search Paths为@executable_p…...

PHREEQC模型化学热力学理论和数据库.dat、各种模拟反应平衡反应模拟、化学动力模拟、反应迁移模拟

PHREEQC是一个用于计算多种低温水文地球化学反应的计算机软件&#xff0c;以离子缔合水模型为基础的PHREEQC能够&#xff08;1&#xff09;计算物质形成种类与饱和指数&#xff1b;&#xff08;2&#xff09;模拟地球化学反演过程&#xff1b;&#xff08;3&#xff09;计算批反…...

centos下使用jemalloc解决Mysql内存泄漏问题

参考&#xff1a; MySQL bug&#xff1a;https://bugs.mysql.com/bug.php?id83047&tdsourcetags_pcqq_aiomsg https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md &#xff08;1&#xff09;ptmalloc 是glibc的内存分配管理 &#xff08;2&#xff09;tcmalloc…...

【100天精通python】Day41:python网络爬虫开发_爬虫基础入门

目录 专栏导读 1网络爬虫概述 1.1 工作原理 1.2 应用场景 1.3 爬虫策略 1.4 爬虫的挑战 2 网络爬虫开发 2.1 通用的网络爬虫基本流程 2.2 网络爬虫的常用技术 2.3 网络爬虫常用的第三方库 3 简单爬虫示例 专栏导读 专栏订阅地址&#xff1a;https://blog.csdn.net/…...

开源和自研——机器人

双足机器人&#xff1a; MPC技术&#xff1a;封闭性非常高。没有开源方案可抄。 因为开源&#xff0c;不需要从0构建。 这也是前两年&#xff0c;国外一开源华为就遥遥领先。 射频芯片/射频天线&#xff1a;技术封闭。华为虽然做通信&#xff0c;但却没有攻破。 鸿蒙&#…...

【AIGC 讯飞星火 | 百度AI|ChatGPT| 】智能对比

AI智能对比 &#x1f378; 前言&#x1f37a; 概念类对比&#x1f375; 讯飞&#x1f375; 百度AI&#x1f375; chatGPT &#x1f379; 功能类对比☕ 讯飞☕ 百度AI☕ chatGPT &#x1f943; 可输入字数对比&#x1f964; 百度AI&#x1f964; 讯飞&#x1f964; chatGPT &…...

Wazuh安装及使用

环境配置 官方网址Quickstart Wazuh documentation 可以选择Elastic Stack安装&#xff0c;也可以选择下载虚拟机&#xff08;OVA&#xff09;安装 这里展示虚拟机安装 下载好文档中提供的文件 虚拟机配置要求 在VM左上角 文件->打开->刚刚下载的.ova文件&#xff0c…...

docker pull 设置代理 centos

On CentOS the configuration file for Docker is at: /etc/sysconfig/docker 用 root 权限打开 text editor sudo gedit 注意 加引号 Adding the below line helped me to get the Docker daemon working behind a proxy server: HTTP_PROXY“http://<proxy_host>:&…...

仪表板展示 | DataEase看中国:2023年中国电影市场分析

背景介绍 随着《消失的她》、《变形金刚&#xff1a;超能勇士崛起》、《蜘蛛侠&#xff1a;纵横宇宙》、《我爱你》等国内外影片的上映&#xff0c;2023年上半年的电影市场也接近尾声。据国家电影专资办初步统计&#xff0c;上半年全国城市院线票房达262亿元&#xff0c;已经超…...

在APP中如何嵌入小游戏?

APP内嵌游戏之所以能火爆&#xff0c;主要是因为互联网对流量的追求是无止境的&#xff0c;之前高速增长的红利期后&#xff0c;获取新的流量成为各大厂商的挑战&#xff0c;小游戏的引入&#xff0c;就是这个目的&#xff0c;为已有的产品赋能&#xff0c;抢占用户注意力和使用…...

神经网络基础-神经网络补充概念-02-逻辑回归

概念 逻辑回归是一种用于二分分类问题的统计学习方法&#xff0c;尽管名字中带有"回归"一词&#xff0c;但实际上它用于分类任务。逻辑回归的目标是根据输入特征来预测数据点属于某个类别的概率&#xff0c;然后将概率映射到一个离散的类别标签。 逻辑回归模型的核…...

DICOM图像的常用一些参数解析

医学图像DICOM医学影像文件格式详解 Dicom文件基本操作 DICOM图像参数&#xff1f; 像素&#xff1a;构成图片的小色点。图像每个维度的像素个数——该维度一共有多少个均匀分布的像素点。 分辨率&#xff08;单位DPI&#xff09;&#xff1a;每英寸&#xff08;Inch&#xf…...

Java虚拟机(JVM):虚拟机栈溢出

一、概念 Java虚拟机栈溢出&#xff08;Java Virtual Machine Stack Overflow&#xff09;是指在Java程序中&#xff0c;当线程调用的方法层级过深&#xff0c;导致栈空间溢出的情况。 Java虚拟机栈是每个线程私有的&#xff0c;用于存储方法的调用和局部变量的内存空间。每当…...

MySQL流程控制

流程控制 顺序结构&#xff1a; 程序从上往下依次执行分支结构&#xff1a; 程序按条件进行选择执行&#xff0c;从两条或多条路径中选择一条执行。循环结构&#xff1a; 程序满足一定条件下&#xff0c;重复执行一组语句 针对于MySQL的流程控制语句主要有3类。注意&#xff…...

智安网络|深入比较:Sass系统与源码系统的差异及选择指南

随着前端开发的快速发展&#xff0c;开发人员需要使用更高效和灵活的工具来处理样式表。在这个领域&#xff0c;Sass系统和源码系统是两个备受关注的选项。 Sass系统 Sass&#xff08;Syntactically Awesome Style Sheets&#xff09;是一种CSS预处理器&#xff0c;它扩展了CS…...

Day14 01-Shell脚本编程详解

文章目录 第一章 Shell编程【重点】1.1. Shell的概念介绍1.1.1. 命令解释器4.1.1.2. Shell脚本 1.2. Shell编程规范1.2.1. 脚本文件的结构1.2.2. 脚本文件的执行 1.3. Shell的变量1.3.1. 变量的用法1.3.2. 变量的分类1.3.3. 局部变量1.3.4. 环境变量1.3.5. 位置参数变量1.3.6. …...

NVIDIA GPU驱动和CUDA工具包 Linux CentOS 7 在线安装指南

挑选指定系统和对应的GPU型号下载驱动和CUDA工具包: Linux CentOS安装NVIDIA GPU驱动程序和NVIDIA CUDA工具包_centos安装显卡驱动和cuda_Entropy-Go的博客-CSDN博客 相比之下&#xff0c;本文是在线安装NVIDIA GPU驱动和CUDA工具包方式&#xff0c;省去挑选对应正确安装包的烦…...

Php“牵手”拼多多商品详情页数据采集方法,拼多多API接口申请指南

拼多多详情接口 API 是开放平台提供的一种 API 接口&#xff0c;它可以帮助开发者获取商品的详细信息&#xff0c;包括商品的标题、描述、图片等信息。在电商平台的开发中&#xff0c;详情接口API是非常常用的 API&#xff0c;因此本文将详细介绍详情接口 API 的使用。 一、拼…...

未来公文的智能化进程

随着技术的飞速发展&#xff0c;公文——这个有着悠久历史的官方沟通方式&#xff0c;也正逐步走向智能化的未来。自动化、人工智能、区块链...这些现代科技正重塑我们的公文制度&#xff0c;让其变得更加高效、安全和智慧。 1.语义理解与自动生成 通过深度学习和NLP&#xff…...

C语言:深度学习知识储备

目录 数据类型 每种类型的大小是多少呢&#xff1f; 变量 变量的命名&#xff1a; 变量的分类&#xff1a; 变量的作用域和生命周期 作用域&#xff1a; 生命周期&#xff1a; 常量 字符串转义字符注释 字符串&#xff1a; 转义字符 操作符&#xff1a; 算术操作符…...

探索大模型时代下的算法工程师前景与发展路径

文章目录 大模型时代的挑战与机遇从算法到工程&#xff1a;技能升级的必要性发展路径与职业规划路径一&#xff1a;深耕研究领域路径二&#xff1a;工程实践与部署路径三&#xff1a;跨界合作与解决复杂问题路径四&#xff1a;教育培训和技术普及 不断学习与更新知识结论 &…...

【福建事业单位-综合基础知识】03行政法

【福建事业单位-综合基础知识】03行政法 1.行政法概述&#xff08;原则重点&#xff09;行政主体范围 行政行为总结 二.行政处罚2.1行政处罚的种类总结 行政法框架 1.行政法概述&#xff08;原则重点&#xff09; 行政法的首要原则是合法&#xff1b;自由裁量——合理行政&…...

CSS 背景属性

前言 背景属性 属性说明background-color背景颜色background-image背景图background-repeat背景图平铺方式background-position背景图位置background-size背景图缩放background-attachment背景图固定background背景复合属性 背景颜色 可以使用background-color属性来设置背景…...

小白到运维工程师自学之路 第七十五集 (Kubernetes 企业级高可用部署)2

8、添加master节点 在k8s-master2和k8s-master3节点创建文件夹 mkdir -p /etc/kubernetes/pki/etcd在k8s-master1节点执行 从k8s-master1复制密钥和相关文件到k8s-master2和k8s-master3 scp /etc/kubernetes/admin.conf root192.168.77.15:/etc/kubernetes scp /etc/kubernet…...

Educational Codeforces Round 62 (Rated for Div. 2) C. Playlist

一开始肯定要排个序&#xff0c;b相同时t大的在前边&#xff0c;不同时b大的在前面。 然后想最多只能选k个的限制&#xff0c;可以这样想&#xff0c;每次用到的b只能用已选到的最小的值&#xff0c;那可以把每个b都枚举一遍&#xff0c;然后每一次选时长最长的&#xff0c;且…...

postgresql中基础sql查询

postgresql中基础sql查询 创建表插入数据创建索引删除表postgresql命令速查简单查询计算查询结果 利用查询条件过滤数据模糊查询 创建表 -- 部门信息表 CREATE TABLE departments( department_id INTEGER NOT NULL -- 部门编号&#xff0c;主键, department_name CHARACTE…...

如何做好科技文献资料的翻译!

我们知道&#xff0c;科技文献是工程技术人员的重要参考文献&#xff0c;翻译科技文献资料有助于促进国内外科技知识和技术的传播。那么&#xff0c;如何做好科技文献资料的翻译&#xff0c;专业科技文献翻译哪家好&#xff1f; 据了解&#xff0c;科技文献翻译是一种以应用为主…...

处理Selenium3+python3定位鼠标悬停才显示的元素

这篇文章主要介绍了Selenium3python3--如何定位鼠标悬停才显示的元素 &#xff0c;文中通过简单代码给大家介绍的非常详细,需要的朋友可以参考下 先给大家介绍下Selenium3python3--如何定位鼠标悬停才显示的元素 定位鼠标悬停才显示的元素&#xff0c;要引入新模块 # coding…...

python通过S7协议读取西门子200smart数据

发现网上很多关于python通过s7协议控制200smart的代码都失败&#xff0c;我猜应该是版本的问题。自己捣鼓了半天&#xff0c;终于测试成功 from snap7 import util,clientmy_plc client.Client() #建立一个客户端对象 my_plc.set_connection_type(3) #如果是200smart,必须有此…...

深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)

深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)。 一、简介 单点登录(Single Sign On),简称为 SSO。 它的解释是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 ❝ 所谓一次登录,处处登录。同样一处退出,处处退出。 ❞ 二…...

【云原生】K8S控制详解

目录 一、Pod控制器1.1 Pod控制器及其功用1.2 pod控制器有多种类型1.3Pod与控制器之间的关系二、Deployment 三、SatefulSet3.1从上面的应用场景可以发现&#xff0c;StatefulSet由以下几个部分组成&#xff1a;3.2为什么要有headless&#xff1f;3.3为什么要有volumeClaimTemp…...