Bean的实例化方式

1. 通过构造方法实例化(Constructor Instantiation)

这是最常见的方式,Spring通过调用类的构造方法来创建Bean实例。

XML配置示例

<bean id="userDao" class="com.example.UserDao" />
  • Spring容器在加载时调用UserDao无参构造函数进行实例化。
带参数的构造器注入

如果类没有无参构造器,需要传递参数时,可以在XML中使用<constructor-arg>标签。

<bean id="userService" class="com.example.UserService"><constructor-arg name="userDao" ref="userDao" />
</bean>

 对应的Java类:

public class UserService {private UserDao userDao;public UserService(UserDao userDao) {this.userDao = userDao;}
}

2. 通过静态工厂方法实例化(Static Factory Method)

使用静态方法创建Bean实例,适用于无法直接通过构造器创建的对象。

XML配置示例

<bean id="connection" class="com.example.ConnectionFactory" factory-method="createConnection" />

对应的Java类:

public class ConnectionFactory {public static Connection createConnection() {return new Connection();}
}

Spring容器会调用ConnectionFactory.createConnection()返回Connection对象。

3. 通过实例工厂方法实例化(Instance Factory Method)

使用已经创建的工厂实例来创建Bean。

XML配置示例

<bean id="factory" class="com.example.ConnectionFactory" /><bean id="connection" factory-bean="factory" factory-method="getConnection" />

 对应的Java类:

public class ConnectionFactory {public Connection getConnection() {return new Connection();}
}

Spring首先实例化ConnectionFactory对象,然后调用其getConnection()方法创建Connection实例。

4. 通过工厂Bean(FactoryBean接口)实例化

Spring提供了FactoryBean接口,用于更复杂的对象创建逻辑。实现此接口的类会被Spring识别为工厂。它允许开发者通过实现 FactoryBean 接口,来自定义 Bean 的实例化逻辑。当需要创建一个复杂对象或对象的创建过程需要包含一些逻辑操作时,FactoryBean 是非常有用的。

FactoryBean接口详解

FactoryBean<T> 是一个泛型接口,其中 T 是由该工厂创建的对象类型。实现 FactoryBean 接口的类可以被 Spring 容器用作工厂。其中,T 是一个泛型参数,它表示由工厂创建的对象的类型。在实现 FactoryBean 接口时,需要指定这个泛型参数的具体类型,即工厂将返回的对象的类型

以下是 FactoryBean 接口的关键方法:

  • T getObject(): 定义如何创建和返回一个 Bean 实例。
  • Class<?> getObjectType(): 返回创建的对象类型。
  • boolean isSingleton(): 返回是否创建的对象是单例模式。

Java代码

public class MyBeanFactory implements FactoryBean<MyBean> {@Overridepublic MyBean getObject() {return new MyBean();}@Overridepublic Class<?> getObjectType() {return MyBean.class;}@Overridepublic boolean isSingleton() {return true;  // 如果要让 Spring 管理它为单例,可以返回 true}
}

 XML配置

<bean id="myBean" class="com.example.MyBeanFactory" />

Spring会调用MyBeanFactorygetObject()方法,返回MyBean实例。

FactoryBean的工作原理

在 Spring 中,当你使用 <bean> 配置来定义一个实现了 FactoryBean 接口的类时,Spring 容器实际上不会直接将这个类本身作为 Bean,而是通过调用 FactoryBeangetObject() 方法来创建 Bean 实例。

BeanFactory和FactoryBean的区别

  • BeanFactorySpring IoC容器的顶级对象 ,是 Spring 的一个核心接口,负责管理和提供 Bean 的实例,是 Spring IoC 容器的基础接口。
  • FactoryBean:是一个特殊的 Bean,用于创建复杂 Bean 实例。它是 Spring 框架中用来实现工厂模式的一种机制,允许自定义创建复杂对象的逻辑。总之,它是一个Bean,是一个能够辅助Spring实例化其它Bean对象的一个Bean。

BeanFactory 详细解释

  • BeanFactory 是 Spring IoC 容器的最基础接口,提供 Bean 的实例管理功能。
  • 它负责 Bean 的创建、管理和生命周期控制
  • 实现类ApplicationContextBeanFactory 的一个子接口,它在 BeanFactory 的基础上增加了更多的企业级功能,通常我们在开发中更多地使用 ApplicationContext

工作方式

  • 延迟加载:默认情况下,BeanFactory 在第一次被请求时才创建 Bean 的实例(延迟加载)。这有助于提高应用的启动速度。
  • 提供方法来获取 Bean,如 getBean(String beanName)
    BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
    MyService myService = (MyService) factory.getBean("myService");
    

FactoryBean 详细解释

  • FactoryBean 是一个实现了 FactoryBean 接口的特殊 Bean,它用于自定义创建复杂对象
  • 实现 FactoryBean 接口的类本质上是一个工厂类,Spring 通过调用 FactoryBeangetObject() 方法,来创建和管理最终的 Bean。
  • FactoryBean 提供了一种方式,可以将对象的创建细节封装到工厂中,这种方式特别适合创建需要复杂初始化过程的 Bean。

核心方法

  • getObject():返回工厂创建的对象。
  • getObjectType():返回创建的对象的类型。
  • isSingleton():指示是否创建单例实例
 FactoryBean 的应用场景:
注入自定义Date:

之前了解过:java.util.Date在Spring中被当做简单类型,简单类型在注入的时候可以直接使用value属性或value标签来完成。但对于Date类型来说,采用value属性或value标签赋值的时候,对日期字符串的格式要求非常严格,必须是这种格式的:Mon Oct 10 14:30:26 CST 2022。其他格式是不会被识别的。

Student类:

package bean;import java.util.Date;public class Student {private String name;private Date birth;public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getBirth() {return birth;}public void setBirth(Date birth) {this.birth = birth;}public Student() {}public Student(String name, Date birth) {this.name = name;this.birth = birth;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", birth=" + birth +'}';}
}

如果我们想使用一下形式注入到Date类中,我们就需要使用到FactoryBean

<bean id="studentBean" class="com.powernode.spring6.bean.Student"><property name="birth" value="2002-10-10"/>
</bean>

编写DateFactoryBean实现FactoryBean接口:

package com.powernode.spring6.bean;import org.springframework.beans.factory.FactoryBean;import java.text.SimpleDateFormat;
import java.util.Date;public class DateFactoryBean implements FactoryBean<Date> {// 定义属性接收日期字符串private String date;// 通过构造方法给日期字符串属性赋值public DateFactoryBean(String date) {this.date = date;}@Overridepublic Date getObject() throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");return sdf.parse(this.date);}@Overridepublic Class<?> getObjectType() {return null;}
}

编写spring配置文件:

<bean id="dateBean" class="com.powernode.spring6.bean.DateFactoryBean"><constructor-arg name="date" value="1999-10-11"/>
</bean><bean id="studentBean" class="com.powernode.spring6.bean.Student"><property name="birth" ref="dateBean"/>
</bean>
  • dateBean 是一个通过工厂创建的日期对象的 Bean。
  • studentBean 是一个 Student 对象,拥有一个名为 birth 的属性,该属性引用了 dateBean

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

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

相关文章

【C语言】自定义类型:结构体--结构体内存对齐(用于计算结构体的大小)

结构体内存对齐 结构体内存对齐用于计算结构体的大小。 &#xff08;1&#xff09;对齐规则 1&#xff09;&#xff09;结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处。 2&#xff09;&#xff09;其他成员变量要对齐到某个数字&#xff08;对齐数&#…

C++中的vector使用与实现

一、vector的使用 1.1 vector的定义 是一种类模板 template < class T, class Alloc allocator<T> > class vector; 其中的模板参数Alloc是在使用空间配置器&#xff08;内存池&#xff09;&#xff0c;并给了缺省值&#xff0c;暂时不深究 1.2遍历方式 1.…

FFmpeg 4.3 音视频-多路H265监控录放C++开发四 :RGB颜色

一 RGB 的意义&#xff1f; 为什么要从RGB 开始讲起呢&#xff1f; 因为最终传输到显卡显示器的颜色都是RGB 即使能处理YUV的API&#xff0c;本质上也是帮你做了从 YUV 到 RGB的转换。 RGB888 表示 R 占8bit&#xff0c;G 占8bit&#xff0c;B 占8bit&#xff0c;也就是每一…

Gin框架操作指南10:服务器与高级功能

官方文档地址&#xff08;中文&#xff09;&#xff1a;https://gin-gonic.com/zh-cn/docs/ 注&#xff1a;本教程采用工作区机制&#xff0c;所以一个项目下载了Gin框架&#xff0c;其余项目就无需重复下载&#xff0c;想了解的读者可阅读第一节&#xff1a;Gin操作指南&#…

STM32端与C#端的连接与交互[外设][代码记录]

1. 通过UART串口进行通信 STM32 端代码&#xff08;UART通信&#xff09;&#xff1a; #include "stm32f1xx_hal.h"UART_HandleTypeDef huart1;void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void);int main(v…

手撕布隆过滤器:原理解析与面试心得

前言 说来话长&#xff0c;话来说长。前些天我投了一些日常实习的简历&#xff0c;结果足足等了两个礼拜才收到面试通知&#xff0c;看来如今的行情确实是挺紧张的。当时我是满怀信心去的&#xff0c;心想这次一定要好好拷打面试官一番&#xff0c;结果没想到&#xff0c;自我…

QT程序报错解决方案:Cannot queue arguments of type ‘QTextCharFormat‘ 或 ‘QTextCursor‘

项目场景&#xff1a; 项目场景&#xff1a;基于QT实现的C某程序&#xff0c;搭载在Linux环境中。 问题描述 执行程序时&#xff0c;发现log中报错如下内容&#xff1a; QObject::connect: Cannot queue arguments of type QTextCharFormat (Make sure QTextCharFormat is r…

Cesium for UE-04-一些说明

目前主要做webgis的工作&#xff0c;UE官方对web的支持截止到了4.23版本&#xff0c;即使是4.23版本之后的4.xx版本也有办法支持&#xff0c;已经有大佬开源了一些方法和工具&#xff0c;不再介绍。即使是4.23想要输出为h5&#xff0c;也是有一定的折腾门槛的。最重要的是【Ces…

腰背肌筋膜炎有哪些治疗方法

腰背肌筋膜炎主要表现为腰背部的疼痛、酸胀、僵硬、活动受限等症状。在疾病初期&#xff0c;症状可能相对较轻&#xff0c;通过休息、保暖、适当的物理治疗等&#xff0c;往往可以缓解症状&#xff0c;此时病情不算严重。如果患者不重视&#xff0c;继续保持不良的生活习惯&…

微服务架构 --- 使用RabbitMQ进行异步处理

目录 一.什么是RabbitMQ&#xff1f; 二.异步调用处理逻辑&#xff1a; 三.RabbitMQ的基本使用&#xff1a; 1.安装&#xff1a; 2.架构图&#xff1a; 3.RabbitMQ控制台的使用&#xff1a; &#xff08;1&#xff09;Exchanges 交换机&#xff1a; &#xff08;2&#…

MES系列-报表和分析

MES系列-报表和分析 MES系列文章目录 ISA-95制造业中企业和控制系统的集成的国际标准-(1) ISA-95制造业中企业和控制系统的集成的国际标准-(2) ISA-95制造业中企业和控制系统的集成的国际标准-(3) ISA-95制造业中企业和控制系统的集成的国际标准-(4) ISA-95制造业中企业和控制…

1.1_Metasploit (MSF) 工具使用

MetaSploit 漏洞利用框架 模块功能 模块功能Auxiliary信息收集&#xff0c;漏洞扫描等辅助功能Payloads漏洞验证代码Exploits包含漏洞利用脚本Encoders绕过检测和过滤Evasion绕过杀软PostExploits 执行成功&#xff0c;向目标主机发送的一些功能指令Nops溢出攻击 目录说明 目录…

Fuse.js 的原理:背后的算法与机制

前言 了解 Fuse.js 的原理&#xff0c;有助于我们更好地理解它的强大之处以及它是如何实现高效模糊搜索的。Fuse.js 的核心原理主要涉及两个方面&#xff1a;模糊搜索算法和数据结构处理。 模糊搜索算法 Fuse.js 使用了一种基于 Bitap 算法&#xff08;也叫做 Shift-Or、Shi…

【Flutter】Dart:运算符

在 Dart 中&#xff0c;运算符是非常重要的组成部分&#xff0c;它们可以对变量和常量进行多种运算操作。理解和掌握 Dart 中的各种运算符不仅可以帮助你编写更加高效、简洁的代码&#xff0c;还能更好地理解其背后的逻辑和设计。本文将深入探讨 Dart 中的运算符&#xff0c;包…

什么是不同类型的微服务测试?

大家好&#xff0c;我是锋哥。今天分享关于【什么是不同类型的微服务测试&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 什么是不同类型的微服务测试&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 微服务架构中的测试可以分为多种类…

WPF基础权限系统

一.开发环境 VisualStudio 2022NET SDK 8.0Prism 版本 8.1.97Sqlite 二. 功能介绍 WPF 基础权限系统&#xff0c;是一个支持前后端分离设计的 客户端(C/S)项目&#xff0c;该示例项目前端xaml使用UI库 &#xff0c;Material Design Themes UI 来构建用户界面&#xff0c;确保…

【into outfile写文件】

简介 select * from user into outfile C:/Users/ichunqiu/Desktop/PhpStudy2018/PHPTutorial/WWW/1.txt;用法的意思就是把user表中查询到的所有字段都导出到1.txt文件中 我们之前还有学到dumpfile&#xff0c;单是它只能导出一条数据 写入shell 测试注入点 usernameadmin&…

【工具】使用perf抓取火焰图

背景 当程序存在cpu性能问题时&#xff0c;我们需要找到是哪个函数占用较多的CPU&#xff0c;也就是找出热点函数&#xff1b;perf的火焰图就是这个用途 安装 在Linux系统中&#xff0c;perf 是 Linux 内核提供的性能分析工具&#xff0c;它通常包含在内核源代码包中。大多数…

编码方式知识整理【ASCII、Unicode和UTF-8】

编码方式 一、ASCII编码二、Unicode 编码三、UTF-8编码四、GB2312编码五、GBK编码 计算机中对数据的存储为二进制形式&#xff0c;但采用什么样的编码方式存储&#xff0c;效率更高。主要编码方式有 ASCII、Unicode、UTF-8等。 英文一般为1个字节&#xff0c;汉字一般为3个字节…

Linux 线程互斥

1.相关背景概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源 临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区 #include <iostream> #include <pthread.h> #include <string> #include <vector…