SpringFramewrok (1)

news2024/11/18 15:27:47

1、框架的概念与理解

在现实生活中,框架可以比喻为我们搭建房子的框架。

在框架的基础上,我们可以专注于我们自己的工作,而不用在意这些底层工作如何实现。

框架的优点包括以下几点:

1. 提高开发效率:框架提供了许多预先设计好了的组件和工具,能够帮助开发人员快速进行开发。相较于传统手写代码,在框架提供的规范化环境中,开发者可以更快地实现项目的各种要求。
2. 降低开发成本:框架的提供标准化的编程语言、数据操作等代码片段,避免了重复开发的问题,降低了开发成本,提供深度优化的系统,降低了维护成本,增强了系统的可靠性。
3. 提高应用程序的稳定性:框架通常经过了很长时间的开发和测试,其中的许多组件、代码片段和设计模式都得到了验证。重复利用这些组件有助于减少bug的出现,从而提高了应用程序的稳定性。
4. 提供标准化的解决方案:框架通常是针对某个特定领域的,通过提供标准化的解决方案,可以为开发人员提供一种共同的语言和思想基础,有助于更好地沟通和协作。

框架的缺点包括以下几个方面:

1. 学习成本高:框架通常具有特定的语言和编程范式。对于开发人员而言,需要花费时间学习其背后的架构、模式和逻辑,这对于新手而言可能会耗费较长时间。
2. 可能存在局限性:虽然框架提高了开发效率并可以帮助开发人员解决常见问题,但是在某些情况下,特定的应用需求可能超出框架的范围,从而导致应用程序无法满足要求。开发人员可能需要更多的控制权和自由度,同时需要在框架和应用程序之间进行权衡取舍。
3. 版本变更和兼容性问题:框架的版本发布和迭代通常会导致代码库的大规模变更,进而导致应用程序出现兼容性问题和漏洞。当框架变更时,需要考虑框架是否向下兼容,以及如何进行适当的测试、迁移和升级。
4. 架构风险:框架涉及到很多抽象和概念,如果开发者没有足够的理解和掌握其架构,可能会导致系统出现设计和架构缺陷,从而影响系统的健康性和安全性。

站在文件结构的角度理解框架,可以将框架总结:框架 = jar包+配置文件

对于java框架,其实就是提前写好的jar包,将底层的代码实现封装,只对我们提供一个接口API的使用,但是框架也要包含配置文件,即我们可以动态去配置一些内容,而不是只可以简单的使用其api

2、SpringFrameWork介绍

1.1 Spring与SpringFrame

 1.1 .1 Spring(技术栈)

广义上的 Spring 泛指以 Spring Framework 为基础的 Spring 技术栈。

经过十多年的发展,Spring 已经不再是一个单纯的应用框架,而是逐渐发展成为一个由多个不同子项目(模块)组成的成熟技术,例如 Spring Framework、Spring MVC、SpringBoot、Spring Cloud、Spring Data、Spring Security 等,其中 Spring Framework 是其他子项目的基础。

这些子项目涵盖了从企业级应用开发到云计算等各方面的内容,能够帮助开发人员解决软件发展过程中不断产生的各种实际问题,给开发人员带来了更好的开发体验。

1.1.2 SpringFrameWork(框架)

狭义的 Spring 特指 Spring Framework,通常我们将它称为 Spring 框架。

Spring Framework(Spring框架)是一个开源的应用程序框架,由SpringSource公司开发,最初是为了解决企业级开发中各种常见问题而创建的。它提供了很多功能,例如:依赖注入(Dependency Injection)、面向切面编程(AOP)、声明式事务管理(TX)等。其主要目标是使企业级应用程序的开发变得更加简单和快速,并且Spring框架被广泛应用于Java企业开发领域。

Spring全家桶的其他框架都是以SpringFramework框架为基础!

1.2 SpringFrameWork框架的主要功能模块

框架结构图:

3、Spring IOC 容器与核心概念

3.1组件与组件管理的概念

3.1.1什么是组件

组件其实就是一个可以重复的对象,组件一定是对象,但对象不一定是容器(因为有的对象使用一次就被销毁了)。

回顾常规的三层架构处理请求流程:整个项目其实就是有多个组件搭建而成的。

只不过在没有Spring容器时,我们需要自己去实例化组件对象,并为其赋值以及一些其它操作。有了Spring,就可以大大简化我们的操作。

3.1.2 Spring充当组件管理角色。

组件可以完全交给Spring 框架进行管理,Spring框架替代了程序员原有的new对象和对象属性赋值动作等!

Spring具体的组件管理动作包含:

- 组件对象实例化
- 组件属性属性赋值
- 组件对象之间引用
- 组件对象存活周期管理
- ......

我们只需要编写元数据(配置文件)告知Spring 管理哪些类组件和他们的关系即可!

注意:组件是映射到应用程序中所有可重用组件的Java对象,应该是可复用的功能对象!

- 组件一定是对象
- 对象不一定是组件

综上所述,Spring 充当一个组件容器,创建、管理、存储组件,减少了我们的编码压力,让我们更加专注进行业务编写!

3.1.4 组件交给Spring管理优势
 

  1. 降低了组件之间的耦合性:Spring IoC容器通过依赖注入机制,将组件之间的依赖关系削弱,减少了程序组件之间的耦合性,使得组件更加松散地耦合。
  2. 提高了代码的可重用性和可维护性:将组件的实例化过程、依赖关系的管理等功能交给Spring IoC容器处理,使得组件代码更加模块化、可重用、更易于维护。
  3. 方便了配置和管理:Spring IoC容器通过XML文件或者注解,轻松的对组件进行配置和管理,使得组件的切换、替换等操作更加的方便和快捷。
  4. 交给Spring管理的对象(组件),方可享受Spring框架的其他功能(AOP,声明事务管理)等。 

java代码中也会有自己的组件,但是java代码中的组件并不能享受Spring框架的其它功能。而交给Spring管理的组件,可以享用。

3.2 SpringIOC 容器与容器实现

3.2.1 普通与复杂容器

普通容器 :

只有存储功能,比如 list,set等。像我们日常生活中的杯子一样,只能装水,并没有其它复杂功能。

复杂容器:

除了存储,还有管理组件周期等其它复杂功能。可以用我们日常生活中的政府来举例,我们一生都要在政府的规定下做事,政府管理我们的一生,比如出生的出生证明....

3.2.2 Spring IOC容器介绍

Spring IoC 容器,负责实例化、配置和组装 bean(组件)。容器通过读取配置元数据来获取有关要实例化、配置和组装组件的指令。配置元数据以 XML、Java 注解或 Java 代码形式表现。它允许表达组成应用程序的组件以及这些组件之间丰富的相互依赖关系。

有了Spring IOC容器,我们只需要编写配置元数据以及获取组件。

那我们获取组件的容器的具体接口是什么呢?就是通过哪个API来获取 Spring为我们管理的组件呢?

3.2.3 Spring IoC 容器接口与实现类

SpringIoc容器接口: 

`BeanFactory` 接口提供了一种高级配置机制,能够管理任何类型的对象,它是SpringIoC容器标准化超接口!

`ApplicationContext` 是 `BeanFactory` 的子接口。它扩展了以下功能:

- 更容易与 Spring 的 AOP 功能集成
- 消息资源处理(用于国际化)
- 特定于应用程序给予此接口实现,例如Web 应用程序的 `WebApplicationContext`

简而言之, `BeanFactory` 提供了配置框架和基本功能,而 `ApplicationContext` 添加了更多特定于企业的功能。 `ApplicationContext` 是 `BeanFactory` 的完整超集!

ApplicationContext容器实现类:

容器接口只是一些规范,但并没有具体实现,我们需要通过容器的具体实现类才能获取我们的组件。

以下列出的并不是全部,而是一些我们经常使用的。通过配置文件的格式以及项目属性的不同有不同的容器实现类接口。通过该容器实现类,我们可以通过配置文件来获取具体的Spring容器,从从而来更好更简便的管理我们的组件。

3.2.4 SpringIoc 容器配置管理方式

Spring框架提供了多种配置方式:XML配置方式、注解方式和Java配置类方式

1. XML配置方式:是Spring框架最早的配置方式之一,通过在XML文件中定义Bean及其依赖关系、Bean的作用域等信息,让Spring IoC容器来管理Bean之间的依赖关系。该方式从Spring框架的第一版开始提供支持。
2. 注解方式:从Spring 2.5版本开始提供支持,可以通过在Bean类上使用注解来代替XML配置文件中的配置信息。通过在Bean类上加上相应的注解(如@Component, @Service, @Autowired等),将Bean注册到Spring IoC容器中,这样Spring IoC容器就可以管理这些Bean之间的依赖关系。
3. Java配置类方式:从Spring 3.0版本开始提供支持,通过Java类来定义Bean、Bean之间的依赖关系和配置信息,从而代替XML配置文件的方式。Java配置类是一种使用Java编写配置信息的方式,通过@Configuration、@Bean等注解来实现Bean和依赖关系的配置。

3.3 Spring Ioc/DI 总结

3.3.1 IOC容器

Spring IoC 容器,负责实例化、配置和组装 bean(组件)核心容器。容器通过读取配置元数据来获取有关要实例化、配置和组装组件的指令。

3.3.2 IOC(Inversion of Control)控制反转

IoC 主要是针对对象的创建和调用控制而言的,也就是说,当应用程序需要使用一个对象时,不再是应用程序直接创建该对象,而是由 IoC 容器来创建和管理,即控制权由应用程序转移到 IoC 容器中,也就是“反转”了控制权。这种方式基本上是通过依赖查找的方式来实现的,即 IoC 容器维护着构成应用程序的对象,并负责创建这些对象。

3.3.3 DI(Dependency Injection)依赖注入

DI 是指在组件之间传递依赖关系的过程中,将依赖关系在容器内部进行处理,这样就不必在应用程序代码中硬编码对象之间的依赖关系,实现了对象之间的解耦合。在 Spring 中,DI 是通过 XML 配置文件或注解的方式实现的。它提供了三种形式的依赖注入:构造函数注入、Setter 方法注入和接口注入。

4、Spring IOC/DI 实践和应用

4.1 实现步骤

我们总结下,组件交给Spring IoC容器管理,并且获取和使用的基本步骤!

1.配置元数据(配置)

配置元数据,既是编写交给SpringIoC容器管理组件的信息,配置方式有三种。

基于 XML 的配置元数据的基本结构:

<bean id="..." [1] class="..." [2]>  
    <!-- collaborators and configuration for this bean go here -->
  </bean>

<?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
    https://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="..." [1] class="..." [2]>  
    <!-- collaborators and configuration for this bean go here -->
  </bean>

  <bean id="..." class="...">
    <!-- collaborators and configuration for this bean go here -->
  </bean>
  <!-- more bean definitions go here -->
</beans>

Spring IoC 容器管理一个或多个组件。这些 组件是使用你提供给容器的配置元数据(例如,以 XML `<bean/>` 定义的形式)创建的。

<bean /> 标签 == 组件信息声明

- `id` 属性是标识单个 Bean 定义的字符串。
- `class` 属性定义 Bean 的类型并使用完全限定的类名。

2.实例IOC容器

提供给 `ApplicationContext` 构造函数的位置路径是资源字符串地址,允许容器从各种外部资源(如本地文件系统、Java `CLASSPATH` 等)加载配置元数据。

我们应该选择一个合适的容器实现类,进行IoC容器的实例化工作:

//实例化ioc容器,读取外部配置文件,最终会在容器内进行ioc和di动作
ApplicationContext context = 
           new ClassPathXmlApplicationContext("services.xml", "daos.xml");

3、获取Bean(组件)

`ApplicationContext` 是一个高级工厂的接口,能够维护不同 bean 及其依赖项的注册表。通过使用方法 `T getBean(String name, Class<T> requiredType)` ,您可以检索 bean 的实例。

允许读取 Bean 定义并访问它们,如以下示例所示:

//创建ioc容器对象,指定配置文件,ioc也开始实例组件对象
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
//获取ioc容器的组件对象
PetStoreService service = context.getBean("petStore", PetStoreService.class);
//使用组件对象
List<String> userList = service.getUsernameList();

4.2 基于XML方式的组件管理

4.2.1 组件信息声明配置(ioc)

Spring IoC 容器管理一个或多个 bean。这些 Bean 是使用您提供给容器的配置元数据创建的(例如,以 XML `<bean/>` 定义的形式)。

我们学习,如何通过定义XML配置文件,声明组件类信息,交给 Spring 的 IoC 容器进行组件管理!

一般我们实例化对象的方法有两大类,通过构造函数(包括无参数构造和有参数构造)通过工厂方法(静态工厂和实例化工厂)。在这里我们不讲解有参数构造的实例化,因为有参数构造就相当于DI,即依赖注入,我们等到讲解DI时在讲该构造方法。在这里我们主要演示其它三种。

前提:

创建一个Maven工程

导入相关依赖

   <dependencies>
        <!--spring context依赖-->
        <!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.6</version>
        </dependency>
        <!--junit5测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.3.1</version>
        </dependency>
    </dependencies>

(1)基于无参数的构造函数

当通过构造函数方法创建一个 bean(组件对象) 时,所有普通类都可以由 Spring 使用并与之兼容。也就是说,正在开发的类不需要实现任何特定的接口或以特定的方式进行编码。只需指定 Bean 类信息就足够了。但是,默认情况下,我们需要一个默认(空)构造函数。

a. 准备组件类

b.创建一个spring 的xml配置文件

c.编写配置文件 创建组件

<bean id="happy" class="com_cky.Happy"></bean>

id 是我们组件的唯一标识

class 是组件类的全限定符

注意:要求当前组件类必须包含无参数构造函数!

(2)基于静态工厂方法实例化

a.编写组件信息

package com_cky;

public class Sad {
    private static Sad sad=new Sad();
    private Sad(){};
    public static Sad CreateInstance(){
        return sad;
    }
}

b. xml配置文件编写

<bean id="sad" class="com_cky.Sad" factory-method="CreateInstance"></bean>

- class属性:指定工厂类的全限定符!
- factory-method: 指定静态工厂方法,注意,该方法必须是static方法

(3)基于实例工厂实例化

a. 编写组件类。

package com_cky;

public class Grateful {
    private Grateful grateful=new Grateful();
    public Grateful crateGra(){
        return grateful;
    }
}

b.配置XML文件

<!-- 将工厂类进行ioc配置 -->
<bean id="factory" class="com_cky.Grateful" ></bean>
<!-- 根据工厂对象的实例工厂方法进行实例化组件对象 -->
<bean id="grateful" factory-bean="factory" factory-method="crateGra"></bean>

首先对工厂类进行IOC配置

接着根据工厂对象的实例工厂方法实例化组件对象

- factory-bean属性:指定当前容器中工厂Bean 的名称。
- factory-method:  指定实例工厂方法名。注意,

实例方法必须是非static的!

4.2.2 组件信息配置DI

通过配置文件,实现IoC容器中Bean之间的引用(依赖注入DI配置)。

主要涉及注入场景:基于构造函数的依赖注入和基于 Setter 的依赖注入。

(1)基于构造函数的依赖注入(单个构造参数)

a.编写组件信息

package demo01;

public class UserServe {
}
package demo01;

public class UserDao {
    private UserServe userServe;
    public UserDao(UserServe userServe){
        this.userServe=userServe;
    }
}

b. 编写xml信息

<bean id="userserve" class="demo01.UserServe"></bean>
<bean id="userdao" class="demo01.UserDao">
<constructor-arg ref="userserve"></constructor-arg>
</bean>

constructor-arg标签:可以引用构造参数。 ref引用其他bean的标识。

(2)基于构造函数的依赖注入(多个构造参数)

a.编写组件类

package demo01;

public class UserBook {
    private UserServe userServe;
    private String s;
    public UserBook(String s,UserServe userServe){
        this.s=s;
        this.userServe=userServe;
    }
}

b.编写xml配置类信息

<!--多个参数传参实现DI配置-->
<!--方式1:根据name 传参-->
<bean id="userbook" class="demo01.UserBook">
    <constructor-arg name="s" value="cui"></constructor-arg>
    <constructor-arg name="userServe" ref="userserve"></constructor-arg>
</bean>
<!--方式2:根据索引值传参-->
<bean id="userbook" class="demo01.UserBook">
    <constructor-arg index="1" ref="userserve"></constructor-arg>
<constructor-arg index="0" value="cui"></constructor-arg>
</bean>
<!--方式3:顺序传参-->
<bean id="userbook" class="demo01.UserBook">
    <constructor-arg  value="cui"></constructor-arg>
    <constructor-arg  ref="userserve"></constructor-arg>
</bean>

- constructor-arg标签:指定构造参数和对应的值
- constructor-arg标签:name属性指定参数名、index属性指定参数角标、value属性指定普通属性值 。

(3)基于setter方法注入

a.准备组件类

package demo02;

public class MovieUser {
}
package demo02;

public class MovieSerive {
    private MovieUser movieuser;
    private String movieName;
    public void setMovieSerive(MovieUser movieuser){
        this.movieuser=movieuser;
    }
    public void setMovieName(String s){
        this.movieName=s;
}}

b.编写xml配置

<bean id="movieuser" class="demo02.MovieUser"/>
    <bean id="movieserive" class="demo02.MovieSerive">
        <property name="movieSerive" ref="movieuser"></property>
        <property name="movieName" value="cui"></property>
    </bean>

- property标签: 可以给setter方法对应的属性赋值
- property 标签: name属性代表**set方法标识**、ref代表引用bean的标识id、value属性代表基本属性值 。name是去除setter方法去除set后第一个字母变小写的名字。

4.2.3 Ioc容器的创建与使用

首先我们需要有自己的组件,编写配置信息,之后再去创建ioc容器,通过容器去读取我们的组件信息。

1、容器实例化

//方式1:实例化并且指定配置文件
//参数:String...locations 传入一个或者多个配置文件

ApplicationContext context = 
           new ClassPathXmlApplicationContext("services.xml", "daos.xml");
           
//方式2:先实例化,再指定配置文件,最后刷新容器触发Bean实例化动作 [springmvc源码和contextLoadListener源码方式]  
ApplicationContext context = 
           new ClassPathXmlApplicationContext();   
//设置配置配置文件,方法参数为可变参数,可以设置一个或者多个配置
iocContainer1.setConfigLocations("services.xml", "daos.xml");
//后配置的文件,需要调用refresh方法,触发刷新配置
iocContainer1.refresh();           
 

2、Bean对象读取

 

//方式1: 根据id获取
//没有指定类型,返回为Object,需要类型转化!

HappyComponent happyComponent = 
        (HappyComponent) iocContainer.getBean("bean的id标识");
        
//使用组件对象        
happyComponent.doWork();

//方式2: 根据类型获取
//根据类型获取,但是要求,同类型(当前类,或者之类,或者接口的实现类)只能有一个对象交给IoC容器管理

//配置两个或者以上出现: org.springframework.beans.factory.NoUniqueBeanDefinitionException 问题
HappyComponent happyComponent = iocContainer.getBean(HappyComponent.class);
happyComponent.doWork();

//方式3: 根据id和类型获取
HappyComponent happyComponent = iocContainer.getBean("bean的id标识", HappyComponent.class);
happyComponent.doWork();

根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:『对象 instanceof 指定的类型』的返回结果,
只要返回的是true就可以认定为和类型匹配,能够获取到。

注意:xml配置的组件必须是实现类,不能是接口类。因为我们在代码中需要去实例化该组件。 

4.2.4 组件周期配置方法

1. 周期方法概念

    我们可以在组件类中定义方法,然后当IoC容器实例化和销毁组件对象的时候进行调用!这两个方法我们成为生命周期方法!

    类似于Servlet的init/destroy方法,我们可以在周期方法完成初始化和释放资源等工作。

2.周期方法声明:

a.编写组件类信息:

package demo01;

public class UserServe {
    public void doWork() {
        System.out.println("HappyComponent.doWork");
    }
周期方法要求: 方法命名随意,但是要求方法必须是 public void 无形参列表
    public void init(){
        System.out.println("init");
    }
    public  void clear(){
        System.out.println("destory");
    }
}

b.编写配置类信息

<bean id="userserve" class="demo01.UserServe" init-method="init" 
destroy-method="clear"></bean> 

c.进行测试

public void text_04(){
    //容器实例创建时,就会调用组件的初始化方法。即在refresh这一步,组件就会进行实例化。
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("demo02.xml");
    UserServe userServe=context.getBean("userserve",UserServe.class);
    userServe.doWork();
//销毁组件
    context.close();
}

4.2.5 组件作用域

1、概念

`<bean` 标签声明Bean,只是将Bean的信息配置给SpringIoC容器!

在IoC容器中,这些`<bean`标签对应的信息转成Spring内部 `BeanDefinition` 对象,`BeanDefinition` 对象内,包含定义的信息(id,class,属性等等)!

这意味着,`BeanDefinition`与`类`概念一样,SpringIoC容器可以可以根据`BeanDefinition`对象反射创建多个Bean对象实例。

具体创建多少个Bean的实例对象,由Bean的作用域Scope属性指定!

2、作用域可选值

3.作用域配置

配置scope范围

//默认是单例,singleton 即我们在容器实例化是就会创建一个对象,且每次GetBean都是这一个
在这里我们使用多例,即每次是在getBean时才实例化,这种方式下,每次获取Bean都不是同一个对象。
<bean id="userserve" class="demo01.UserServe" scope="prototype"></bean>

测试

public void text_05(){
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("demo02.xml");
    UserServe userServe=context.getBean("userserve",UserServe.class);
    UserServe userServe1=context.getBean("userserve",UserServe.class);
    System.out.println(userServe1==userServe);
}

//最后输出的是False,因为我们使用的是多例而不是单例。

4.2.6 FactoryBean 特性和使用

1、FactoryBean简介

FactoryBean是一个接口,需要我们实现它的抽象方法。

用于配置复杂的Bean对象,可以将创建过程存储在`FactoryBean` 的getObject方法!

`FactoryBean<T>` 接口提供三种方法

- `T getObject()`: 

    返回此工厂创建的对象的实例。该返回值会被存储到IoC容器!
- `boolean isSingleton()`: 

如果此 `FactoryBean` 返回单例,则返回 `true` ,否则返回 `false` 。此方法的默认实现返回 `true` (注意,lombok插件使用,可能影响效果)。
- `Class<?> getObjectType()`: 返回 `getObject()` 方法返回的对象类型,如果事先不知道类型,则返回 `null` 。

 在实现FactoryBean过程中,一般而言我们只需实现它的 getObject 方法和getObjectType方法即可。

其中最主要的是getObject 方法,我们在该方法中进行复杂对象的配置。

2.FactoryBean 使用场景

1. 代理类的创建
2. 第三方框架整合
3. 复杂对象实例化等

3、应用演示

a.配置组件类

package demo03;

public class JavaBean {
    private  String name;
    public void setName(String name){
        this.name=name;
    }
    public String getName(){
        return name;
    }
}
package demo03;

import org.springframework.beans.factory.FactoryBean;

public class JavaBeanFactoryBean implements FactoryBean<JavaBean> {
    private  String value;
    public void setValue(String value){
        this.value=value;
    }

    /**
     *在xml配置中,property属性是为FactoryBean工厂配置的,而不是为FactoryBean 实例化的对象配置的。
     * 所以 我们不能直接给JavaBean 进行setter注入,在这里我们给工厂实例注入,之后通过工厂实例注入的值传给JavaBean对象。
     */
    @Override
    public JavaBean getObject() throws Exception {
       JavaBean javaBean=new JavaBean();
       javaBean.setName(value);
       return javaBean;
    }

    @Override
    public Class<?> getObjectType() {
        return JavaBean.class;
    }
}

b. 配置xml文件

<bean id="javabean" class="demo03.JavaBeanFactoryBean">
//这里的id属性是给工厂对象JavaBean的id名,ioc不仅会实例化对象JavaBean组件,ioc也会实例化工厂组件,但是工厂组件的名字为&id。<bean>中间都是为工厂组件配置的。
    <property name="value" value="cui"></property>

c.演示

@Test
public void text_06(){
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("demo03.xml");
//注意: 直接根据声明FactoryBean的id,获取的是getObject方法返回的对象
    JavaBean javaBean=context.getBean("javabean", JavaBean.class);
    System.out.println(javaBean);
//如果想要获取FactoryBean对象, 直接在id前添加&符号即可! &id 这是一种固定的约束
    JavaBeanFactoryBean javabeanFactoryBean=context.getBean("&javabean",JavaBeanFactoryBean.class);
    System.out.println(javabeanFactoryBean);
    System.out.println(javaBean.getName());
}

4、FactoryBean与BeanFactory的区别

FactoryBean是一个组件接口,是 Spring 中一种特殊的 bean,可以在 getObject() 工厂方法自定义的逻辑创建Bean!是一种能够生产其他 Bean 的 Bean。FactoryBean 在容器启动时被创建,而在实际使用时则是通过调用 getObject() 方法来得到其所生产的 Bean。因此,FactoryBean 可以自定义任何所需的初始化逻辑,生产出一些定制化的 bean。

一般情况下,整合第三方框架,都是通过定义FactoryBean实现!!!

BeanFactory是IOC容器的最大接口,是 Spring 框架的基础,其作为一个顶级接口定义了容器的基本行为,例如管理 bean 的生命周期、配置文件的加载和解析、bean 的装配和依赖注入等。BeanFactory 接口提供了访问 bean 的方式,例如 getBean() 方法获取指定的 bean 实例。它可以从不同的来源(例如 Mysql 数据库、XML 文件、Java 配置类等)获取 bean 定义,并将其转换为 bean 实例。同时,BeanFactory 还包含很多子类(例如,ApplicationContext 接口)提供了额外的强大功能。

总的来说,FactoryBean 和 BeanFactory 的区别主要在于前者是用于创建 bean 的接口,它提供了更加灵活的初始化定制功能,而后者是用于管理 bean 的框架基础接口,提供了基本的容器功能和 bean 生命周期管理。 

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

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

相关文章

【C++11】 智能指针

一、为什么需要智能指针&#xff1f; 下面我们先分析一下下面这段程序有没有什么内存方面的问题&#xff1f; int div() {int a, b;cin >> a >> b;if (b 0)throw invalid_argument("除0错误");return a / b; }void f() {pair<string, string>* …

Linux编译内核添加Bcache模块

由于Bcache是在linux kernel 3.10之后才加入的&#xff0c;所以要使用Bcache&#xff0c;首先必须确保内核版本至少是3.10或及以上&#xff0c;可以使用uname -a查看内核版本 [rootceph01 ~]# uname -a Linux ceph01 4.18.0-305.3.1.el8.x86_64 #1 SMP Tue Jun 1 16:14:33 UTC…

打桩机液压系统比例阀放大板

打桩机液压系统主要由液压油箱、液压泵、液压马达、各种阀门、管道、油缸、活塞等组成。 打桩机液压系统以液压油为工作介质&#xff0c;利用液压油的压力能来驱动执行机构完成所需的各种动作。打桩机液压系统采用液体进行驱动&#xff0c;可以使打桩机在开启时迅速达到理想工…

el-input单独校验

el-input单独校验,效果图如下 <el-col :span"24"><el-form-item label"修订次数:" prop"sPublish"><el-input-numberv-model"addForm.sPublish":min"0":controls"false":precision"0"p…

10月份stable diffusion animatediff等插件使用指南,又来更新了

插件一直会更新&#xff0c;包含了基本市面上流行的90%插件&#xff0c;好用的插件更是不会错过&#xff0c;往期插件请看往期文章&#xff0c;如果你没有时间一直关注sd更新的进展&#xff0c;请关注我&#xff0c;一个月用几个小时看一下我的文章&#xff0c;最短时间跟进sd。…

在中国可以使用 HubSpot 吗?

当谈到市场营销和客户关系管理工具时&#xff0c;HubSpot通常是一家企业的首选。然而&#xff0c;对于许多中国的企业来说&#xff0c;一个重要的问题是&#xff1a;在中国可以使用HubSpot吗&#xff1f;这个问题涉及到不同的方面&#xff0c;包括政策法规、社交媒体平台、语言…

Flask Web 安装bootstrap失败pip install bootstrap

失败原因&#xff1a;网速太慢了 把公共wifi换成手机热点&#xff0c;成功&#xff1a;&#xff09; &#x1f603; 更新&#xff1a;开了手机热点还是报下面的错&#xff0c;但是把科学上网关了&#xff0c;就成功了&#xff0c;反正就是网络问题

深入使用探讨 PuppeteerSharp 抓取 LinkedIn 页面的步骤

LinkedIn是全球最大的职业社交平台之一&#xff0c;拥有大量的用户和企业信息。用户可以在上面建立个人职业资料、与其他用户建立联系、分享职业经验和获取行业动态。由于其庞大的用户群体和丰富的数据资源&#xff0c;开发者们对于获取LinkedIn数据的需求日益增长。 Puppeteer…

华为云云耀云服务器L实例评测|使用clickhouse-benchmark工具对ClickHouse的性能测试

目录 引言 1 ClickHouse简介 2 利用docker安装ClickHouse 2.1 安装Docker 2.2 下载ClickHouse Docker镜像 2.3 创建ClickHouse容器 2.4 访问ClickHouse 3 创建测试表 4 运行 clickhouse-benchmark 5 分析结果 结语 引言 利用华为云的云耀云服务器L实例&#xff0c…

如何开启POP3/SMTP免费邮件代发授权

如何开启POP3/SMTP免费邮件代发授权 一、开启126、163邮箱的免费邮件代发授权服务&#xff08;获取授权码&#xff09;1.登录“网易邮箱”官网客户端2.进入“设置-邮箱设置-邮箱安全设置”3.进入“POP3/SMTP/IMAP”4.验证并开启“POP3/SMTP”服务5.获取到“POP3/SMTP”授权码 二…

再扩国产化信创版图!朗思科技与中科方德完成产品兼容性互认证

近日&#xff0c;北京朗思智能科技有限公司&#xff08;以下简称“朗思科技”&#xff09;自主研发的数字员工产品与中科方德桌面操作系统完成产品认证。测试结果显示&#xff0c;双方产品完全兼容&#xff0c;整体运行稳定&#xff0c;在功能、性能及兼容性方面表现良好&#…

python数据挖掘从入门到实战

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

C++11——lambda表达式

文章目录 1. C98对自定义类型的排序2. lambda表达式语法2.1 捕捉列表 3. lambda底层原理 1. C98对自定义类型的排序 在C98中&#xff0c;想要对自定义类型就行排序&#xff0c;我们得自己写仿函数来表明我们相对哪一项进行排序 struct Student {Student(string name, long id…

2023年电工(中级)证模拟考试题库及电工(中级)理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年电工&#xff08;中级&#xff09;证模拟考试题库及电工&#xff08;中级&#xff09;理论考试试题是由安全生产模拟考试一点通提供&#xff0c;电工&#xff08;中级&#xff09;证模拟考试题库是根据电工&…

vue3使用swiper6.7.0写轮播图,按钮在轮播图外面

应用场景&#xff1a;需要在header区域&#xff0c;写24小时天气预测轮播&#xff0c;按钮在轮播图外面&#xff0c;默认隐藏左侧按钮&#xff0c;当点击右侧按钮后&#xff0c;左侧按钮显示&#xff0c;当点击到最后一个轮播图的显示时&#xff0c;隐藏右侧按钮。通过获取索引…

使用REPLACE将数据库某一列字段进行字符串操作

REPLACE可以将表里的数据进行替换操作 如&#xff1a;需要把这一列里面的 # 去掉&#xff0c;经过测试&#xff0c;无论是开头、句中还是结尾都可以删除 UPDATE 表名 SET 字段名 REPLACE(字段名 , #, )

解决容器内deepspeed微调大模型报错

解决容器内deepspeed微调大模型报错&#xff1a;[launch.py:315:sigkill_handler] Killing subprocess 问题描述&#xff1a;解决办法 问题描述&#xff1a; 在容器中用deepspeed微调百川大模型2时&#xff0c;出现上述错误&#xff0c;错误是由于生成容器时&#xff0c;共享内…

2023 年值得关注的软件测试趋势(3)

16.云性能工程对业务连续性的影响 检查和改进基于云的应用程序和服务的性能是云性能工程的主要目标&#xff0c;是各种软件测试趋势中云计算的重要组成部分。云提供了无与伦比的可扩展性、灵活性和成本节约&#xff0c;但如果没有适当的性能工程&#xff0c;组织将面临应用程序…

Spark第一课

从数据处理的方式角度: 流式: 一条数据一条数据的处理 微批量: 一小批一小批的处理 批量: 一批数据一批数据的处理(Spark) 从数据处理的延迟角度 离线: 数据处理的延迟是以小时,天为单位 准(近)实时: 以秒为单位 实时:延迟以毫秒为单位, Spark是一个批量数据处理的离线数据分…

微积分(一) 函数的极限

前言 微积分“以直代曲”的思想就是将整体非线性化为局部线性的一个经典的例子&#xff0c;尽管高等数学在定义微分时并没有用到一点线性代数的内容。许多非线性问题的处理――譬如流形、微分几何等&#xff0c;最后往往转化为线性问题。 函数 定义&#xff1a;设 x x x 和 …