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.mzph.cn/news/43587.shtml

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

相关文章

【计算机视觉|生成对抗】StackGAN:使用堆叠生成对抗网络进行文本到照片逼真图像合成

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks 链接&#xff1a;[1612.03242] StackGAN: Text to Photo-realistic Image Synthesis…

ViewFs And Federation On HDFS

序言 ViewFs 是在Federation的基础上提出的,用于通过一个HDFS路径来访问多个NameSpace,同时与ViewFs搭配的技术是client-side mount table(这个就是具体的规则配置信息可以放置在core.xml中,也可以放置在mountTable.xml中). 总的来说ViewFs的其实就是一个中间层,用于去连接不…

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

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

无涯教程-Perl - undef函数

描述 此函数未定义EXPR的值。用于标量,列表,哈希,函数或类型范围。在带有诸如undef $hash {$key}之类的语句的哈希上使用&#xff1b;实际上将指定键的值设置为未定义的值。 如果要从哈希中删除元素,请使用delete函数。 语法 以下是此函数的简单语法- undef EXPRundef返回…

Java进阶篇--迭代器模式

目录 同步迭代器&#xff08;Synchronous Iterator&#xff09;&#xff1a; Iterator 接口 常用方法&#xff1a; 注意&#xff1a; 扩展小知识: 异步迭代器&#xff08;Asynchronous Iterator&#xff09;&#xff1a; 常用的方法 注意&#xff1a; 总结&#xff1a…

【学习FreeRTOS】第9章——FreeRTOS任务调度

1.开启任务调度器 vTaskStartScheduler() 作用&#xff1a;用于启动任务调度器&#xff0c;任务调度器启动后&#xff0c; FreeRTOS 便会开始进行任务调度【动态创建任务为例】 创建空闲任务如果使能软件定时器&#xff0c;则创建定时器任务关闭中断&#xff0c;防止调度器开…

Microsoft ISA服务器配置及日志分析

Microsoft ISA 分析器工具&#xff0c;可分析 Microsoft ISA 服务器&#xff08;或 Forefront 威胁管理网关服务器&#xff09;的日志并生成安全和流量报告。支持来自 Microsoft ISA 服务器组件的以下日志&#xff1a; 数据包过滤器ISA 服务器防火墙服务ISA 服务器网络代理服务…

透过源码理解Flutter中widget、state和element的关系

1、framework源码组成 Flutter中widget、state、element的源码位于framework.dart中&#xff0c;整个文件6693行(版本Flutter 3.12.0-14.0.pre.28)。整个代码可划分为若干部分&#xff0c;主要包括key、widget、state、element四部分。 1.1 key 关于key的代码65行到272行&am…

GuLi商城-前端基础Vue-生命周期和钩子函数

下图展示了实例的生命周期。你不需要立马弄明白所有的东西&#xff0c;不过随着你的不断学习和使用&#xff0c;它 的参考价值会越来越高。 VUE 的生命周期指的是组件在创建、运行和销毁过程中所经历的一系列事件&#xff0c;通过这些事件可以 让开发者在不同阶段进行相应的…

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/…

安卓的代码加固和其他安全问题

文章目录 安卓加固apk文件结构dex加固过程 其它安全问题 安卓加固 从App的加固技术来看:主流分为dex加密和so加密,目前来看保护dex文件更为重要,因为dex反编译后的java代码可读性更强。 android-ndk: Native Development Kit 官网解释&#xff1a;这套工具使您能在 Android 应…

Kvm配置ovs网桥

环境&#xff1a;部署在kvm虚拟环境上&#xff08;让虚拟机和宿主机都可以直接从路由器获取到独立ip&#xff09; 1、安装ovs软件安装包并启动服务&#xff08;一般采用源码安装&#xff0c;此处用yum安装&#xff09; yum install openvswitch-2.9.0-3.el7.x86_64.rpm syste…

Git常见操作

一、全局配置命令 配置级别&#xff1a; –local&#xff08;默认&#xff0c;高级优先&#xff09;&#xff1a;只影响本地仓库 –global(中优先级)&#xff1a;只影响所有当前用户的git仓库 –system&#xff08;低优先级&#xff09;&#xff1a;影响到全系统的git仓库 1…

剑指 Offer 40. 最小的k个数(C+实现)

剑指 Offer 40. 最小的k个数https://leetcode.cn/problems/zui-xiao-de-kge-shu-lcof/ 法1&#xff1a;二叉堆 通过最小堆&#xff0c;直接筛选出最小的k个数 vector<int> getLeastNumbers(vector<int>& arr, int k) {priority_queue<int, vector<int>…

YOLOv8改进后效果

数据集 自建铁路障碍数据集-包含路障&#xff0c;人等少数标签。其中百分之八十作为训练集&#xff0c;百分之二十作为测试集 第一次部署 版本&#xff1a;YOLOv5 训练50epoch后精度可达0.94 mAP可达0.95.此时未包含任何改进操作 第二次部署 版本&#xff1a;YOLOv8改进版本 首…

WebRTC | ICE详解

目录 一、Candidate种类与优先级 二、ICE策略 1. iceServers 2. iceTransportPolicy 三、P2P连接 1.Nat类型 &#xff08;1&#xff09;完全锥型NAT &#xff08;2&#xff09;IP限制锥型NAT &#xff08;3&#xff09;端口限制锥型NAT &#xff08;4&#xff09;对称…

iPhone 15受益:骁龙8 Gen 3可能缺席部分安卓旗舰机

明年一批领先的安卓手机的性能可能与今年的机型非常相似。硅成本的上涨可能是原因。 你可以想象&#xff0c;2024年许多最好的手机都会在Snapdragon 8 Gen 3上运行&#xff0c;这是高通公司针对移动设备的顶级芯片系统的更新&#xff0c;尚未宣布。然而&#xff0c;来自中国的…

C#生产流程控制(串行,并行混合执行)

开源框架CsGo https://gitee.com/hamasm/CsGo?_fromgitee_search 文档资料&#xff1a; https://blog.csdn.net/aa2528877987/article/details/132139337 实现效果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37…

Windows11 Docker Desktop 启动 -wsl kernel version too low

系统环境&#xff1a;windows11 1&#xff1a;docker下载 Docker: Accelerated Container Application Development 下载后双击安装即可 安装后启动Docker提示&#xff1a;Docker Desktop -wsl kernel version too low 处理起来也是非常方便 1:管理员身份启动&#xff1a;…

C#程序随系统启动例子 - 开源研究系列文章

今天讲讲C#中应用程序随系统启动的例子。 我们知道&#xff0c;应用程序随系统启动&#xff0c;都是直接在操作系统注册表中写入程序的启动参数&#xff0c;这样操作系统在启动的时候就根据启动参数来启动应用程序&#xff0c;而我们要做的就是将程序启动参数写入注册表即可。此…