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

【Spring】Bean

Spring 将管理对象称为 BeanSpring 可以看作是一个大型工厂,用于生产和管理 Spring 容器中的 Bean。如果要使用 Spring 生产和管理 Bean,那么就需要将 Bean 配置在 Spring 的配置文件中。Spring 框架支持 XMLProperties 两种格式的配置文件,在实际开发中常用 XML 格式的配置文件。

Bean 的配置

通常,在 XML 文件中,根元素为 <beans><beans> 中包含多个 <bean> 子元素,每个 <bean> 定义一个 Bean,并描述 Bean 如何被装配到 Spring 容器中。

<beans><bean/><bean></bean>
</beans>
属性或子元素名称描述
idBeanBeanFactory 中的唯一标识,获取 Bean 实例时需要以此作为索引名称
classBean 的具体实现类,使用类名
scope指定 Bean 实例的作用域
nameBean 的别名,多个别名之间用逗号、空格或分号分隔
<constructor-arg><bean> 元素的子元素,使用构造方法注入,指定构造方法的参数。该元素的 index 属性指定参数的序号,ref属性指定对 BeanFactory 中其他 Bean的引用关系,type 属性指定参数类型,value 属性指定参数的常量值
<property><bean> 元素的子元素,用于设置一个属性。该元素的 name 属性指定 Bean 实例中相应的属性名称,value 属性指定 Bean 的属性值,ref 属性指定属性对 BeanFactory 中其他 Bean 的引用关系
<list><property> 元素的子元素,用于封装 List 或数组类型的依赖注入
<map><property> 元素的子元素,用于封装 Map 类型的依赖注入
<set><property> 元素的子元素,用于封装 Set 类型的依赖注入
<entry><map> 元素的子元素,用于设置一个键值对

Bean 的作用域

Spring 中可以为 Bean 指定作用域:
在这里插入图片描述

Bean 的实例化

Spring 框架中,如果想使用 Spring 容器中的 Bean,需要对其进行实例化。Spring 框架实例化 Bean 有3种方式,即构造方法实例化、静态工厂实例化和实例工厂实例化。

(1)构造方法实例化

Spring 框架中,Spring 容器可以调用 Bean 对应类的无参构造方式来实例化 Bean

public class BookDaoImpl implements BookDao {@Overridepublic void save() {}
}
<bean id="bookDao" class="com.dao.impl.BookDaoImpl"/>

注意:若没有无参构造方法,则将抛出 BeanCreationException 异常

(2)静态工程实例化

在使用静态工厂实例化 Bean 时,开发者需要在工厂类中创建一个静态方法来创建 Bean 的实例。在配置 Bean 时,class 属性指定静态工厂类,同时还需要使用 factory-method 属性指定工厂类中的静态方法:

public class BookDaoImpl implements BookDao {@Overridepublic void save() {}
}// ...
public class BookDaoFactory {public static BookDao getBookDao() {return new BookDaoImpl();}
}
<bean id="bookDao" class="com.factory.BookDaoFactory" factory-method="getBookDao"/>

(3)实例工厂实例化

在使用实例工厂实例化 Bean 时需要我们在工厂类中创建一个实例方法来创建 Bean 的实例。在配置 Bean 时需要使用 factory-bean 属性指定配置的实例工厂,同时还需要使用 factory-method 属性指定实例工厂中的实例方法:

public class BookDaoImpl implements BookDao {@Overridepublic void save() {}
}// ...
public class BookDaoFactory {public BookDao getBookDao() {return new BookDaoImpl();}
}
<bean id="bookDaoFactory" class="com.factory.BookDaoFactory"/>
<bean id="bookDao" factory-method="getBookDao" factory-bean="bookDaoFactory"/>

除了上面的实现方式,还可以对实例工厂实例化方式进行简化,即使用 FactoryBean 实例化 Bean。创建一个实现 FactoryBean 接口的工厂方法,实现统一接口,最后进行配置:

public class BookDaoFactoryBean implements FactoryBean<BookDao> {@Overridepublic BookDao getObject() throws Exception {return new BookDaoImpl();}@Overridepublic Class<?> getObjectType() {return BookDao.class;}@Overridepublic boolean isSingleton() {return true; // 使用单例模式}
}
<bean id="bookDao" class="com.factory.BookDaoFactoryBean"/>

Bean 的生命周期

Bean 的生命周期是指 Bean 从创建到消亡的完整过程。而 Bean 生命周期控制是指在 Bean 创建后到销毁前做一些事情。

public class BookDaoImpl implements BookDao {@Overridepublic void save() {}// 用于实现 bean 初始后对应操作public void init() {System.out.println("init...");}// 用于实现 bean 销毁前对应操作public void destroy() {System.out.println("destroy...");}
}
<bean id="bookDao" class="com.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>

上面是通过配置方法的方式实现 Bean 生命周期控制,也可以通过接口的方式实现 Bean 生命周期控制,实现 InitializingBeanDisposableBean 接口以及对应的方法:

public class BookDaoImpl implements BookDao, InitializingBean, DisposableBean {@Overridepublic void save() {}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("init...");}@Overridepublic void destroy() throws Exception {System.out.println("destroy...");}
}
<bean id="bookDao" class="com.dao.impl.BookDaoImpl"/>

我们运行 Bean 生命周期控制的代码会发现:init 执行了,但是 destroy 没有执行。原因是:程序运行在虚拟机中,在虚拟机启动后,会经历容器初始化、使用 Bean以及关闭/销毁容器三个阶段。然而,这里虚拟机并没有进入关闭/销毁容器阶段就退出了。这里有两种进入关闭/销毁阶段的方式:

(1)在虚拟机退出前,主动关闭容器

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.close();

(2)注册关闭钩子

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.registerShutdownHook(); // 指示在关闭虚拟机之前先关闭容器

Bean 的装配

Bean 的装配可以理解为将 Bean 依赖注入到 Spring 容器中。Spring 容器支持基于 XML 配置的装配、基于注解的装配以及自动装配等多种装配方式。

(1)基于 XML 配置的装配

Spring 中,有两种主要的基于 XML 配置的装配方式:一种是通过属性的 setter 方法进行注入,另一种是通过构造方法进行注入。根据注入的数据类型,这些方式又可以分为引用类型注入和简单类型注入。

  • 使用 setter 方法注入简单类型数据

bean 中定义简单类型数据并提供可访问的 set 方法:

public class BookDaoImpl implements BookDao {private int connectionNum;private String databaseName;public void setConnectionNum(int connectionNum) {this.connectionNum = connectionNum;}public void setDatabaseName(String databaseName) {this.databaseName = databaseName;}
}

配置中使用 property 标签 value 属性注入简单类型数据:

<bean id="bookDao" class="com.dao.impl.BookDaoImpl"><property name="connectionNum" value="10"/><property name="databaseName" value="mysql"/>
</bean>
  • 使用 setter 方法注入引用类型数据

bean 中定义引用类型属性并提供可访问的 set 方法:

public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}
}

配置中使用 property 标签 ref 属性注入引用类型:

<bean id="bookService" class="com.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/>
</bean>
<bean id="bookDao" class="com.dao.impl.BookDaoImpl"/>
  • 使用构造方法注入简单类型数据

bean 中定义简单类型属性并提供可访问的构造方法:

public class BookDaoImpl implements BookDao {private int connectionNum;private String databaseName;public BookDaoImpl(int connectionNum, String databaseName) {this.connectionNum = connectionNum;this.databaseName = databaseName;}
}

配置中使用 constructor-arg 标签 value 属性注入简单类型对象:

<bean id="bookDao" class="com.dao.impl.BookDaoImpl"><constructor-arg name="connectionNum" value="10"/><constructor-arg name="databaseName" value="mysql"/>
</bean>
  • 使用构造方法注入引用类型数据

bean 中定义引用类型属性并提供可访问的构造方法:

public class BookServiceImpl implements BookService {private BookDao bookDao;public BookServiceImpl(BookDao bookDao) {this.bookDao = bookDao;}
}

配置中使用 constructor-arg 标签 ref 属性注入引用类型对象:

<bean id="bookDao" class="com.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.service.impl.BookServiceImpl"><constructor-arg name="bookDao" ref="bookDao"/>
</bean>

(2)基于注解的装配

使用 @Component 定义 bean

@Component("bookDao") // 起名称为 bookDao
public class BookDaoImpl implements BookDao {@Overridepublic void save() {}
}

核心配置文件中通过组件扫描加载 bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.dao"/>
</beans>

另外,Spring 提供了 @Component 注解的三个衍生注解,分别是:

  • @Controller:用于表现层 bean 定义
  • @Service:用于业务层 bean 定义
  • @Repository:用于数据层 bean 定义

(3)自动装配

IoC 容器根据 bean 所依赖的资源在容器中自动查找并注入到 bean 中的过程称为自动装配。自动装配的方式可分为:按类型、按名称、按构造方法和默认。

  • 配置中使用 bean 标签 autowire 属性设置自动装配的类型:
<bean id="bookDao" class="com.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.service.impl.BookServiceImpl" autowire="byType"/>

使用细节

  • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  • 使用按类型装配时(byType)必须保障容器中相同类型的 bean 唯一,推荐使用
  • 使用按名称装配时(byName)必须保障容器中具有指定名称的 bean,因变量名与配置耦合,不推荐使用
  • 自动装配优先级低于 setter 注入与构造器注入,同时出现时自动装配配置失效

(4)集合的注入

public class BookDaoImpl implements BookDao {private int[] array;private List<String> list;private Set<String> set;private Map<String, String> map;private Properties properties;public void setArray(int[] array) {this.array = array;}public void setList(List<String> list) {this.list = list;}public void setSet(Set<String> set) {this.set = set;}public void setMap(Map<String, String> map) {this.map = map;}public void setProperties(Properties properties) {this.properties = properties;}
}
<bean id="bookDao" class="com.dao.impl.BookDaoImpl"><property name="array"><array><value>100</value><value>200</value></array></property><property name="list"><list><value>java se</value><value>java ee</value></list></property><property name="set"><set><value>java se</value><value>java ee</value></set></property><property name="map"><map><entry key="k1" value="v1"/><entry key="k2" value="v2"/></map></property><property name="properties"><props><prop key="k1">v1</prop><prop key="k2">v2</prop></props></property>
</bean>

相关文章:

【Spring】Bean

Spring 将管理对象称为 Bean。 Spring 可以看作是一个大型工厂&#xff0c;用于生产和管理 Spring 容器中的 Bean。如果要使用 Spring 生产和管理 Bean&#xff0c;那么就需要将 Bean 配置在 Spring 的配置文件中。Spring 框架支持 XML 和 Properties 两种格式的配置文件&#…...

深入解析TK技术下视频音频不同步的成因与解决方案

随着互联网和数字视频技术的飞速发展&#xff0c;音视频同步问题逐渐成为网络视频播放、直播、编辑等过程中不可忽视的技术难题。尤其是在采用TK&#xff08;Transmission Keying&#xff09;技术进行视频传输时&#xff0c;由于其特殊的时序同步要求&#xff0c;音视频不同步现…...

为什么要使用Ansible实现Linux管理自动化?

自动化和Linux系统管理 多年来&#xff0c;大多数系统管理和基础架构管理都依赖于通过图形或命令行用户界面执行的手动任务。系统管理员通常使用清单、其他文档或记忆的例程来执行标准任务。 这种方法容易出错。系统管理员很容易跳过某个步骤或在某个步骤上犯错误。验证这些步…...

Android:任意层级树形控件(有效果图和Demo示例)

先上效果图&#xff1a; 1.创建treeview文件夹 2.treeview -> adapter -> SimpleTreeAdapter.java import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ListView; i…...

C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程

引言 C 标准模板库&#xff08;STL&#xff09;提供了一组功能强大的容器类&#xff0c;用于存储和操作数据集合。不同的容器具有独特的特性和应用场景&#xff0c;因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C 的开发者来说&#xff0c;了解这些容…...

C++---类型转换

文章目录 C的类型转换C的4种强制类型转换RTTI C的类型转换 类型转换 内置类型之间的转换 // a、内置类型之间 // 1、隐式类型转换 整形之间/整形和浮点数之间 // 2、显示类型的转换 指针和整形、指针之间 int main() {int i 1;// 隐式类型转换double d i;printf("%d…...

CSS基础学习练习题

编程题 1.为下面这段文字定义字体样式&#xff0c;要求字体类型指定多种、大小为14px、粗细为粗体、颜色为蓝色。 “有规划的人生叫蓝图&#xff0c;没规划的人生叫拼图。​” 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><me…...

TypeScript知识点总结和案例使用

TypeScript 是一种由微软开发的开源编程语言&#xff0c;它是 JavaScript 的超集&#xff0c;提供了静态类型检查和其他一些增强功能。以下是一些 TypeScript 的重要知识点总结&#xff1a; 1. 基本类型 TypeScript 支持多种基本数据类型&#xff0c;包括&#xff1a; numbe…...

解决BUG: Since 17.0, the “attrs“ and “states“ attributes are no longer used.

从Odoo 17.0开始&#xff0c;attrs和states属性不再使用&#xff0c;取而代之的是使用depends和domain属性来控制字段的可见性和其他行为。如果您想要在选择国家之后继续选择州&#xff0c;并且希望在选择了国家之后才显示州字段&#xff0c;您可以使用depends属性来实现这一点…...

单片机GPIO中断+定时器 实现模拟串口接收

单片机GPIO中断定时器 实现模拟串口接收 解决思路代码示例 解决思路 串口波特率9600bps,每个bit约为1000000us/9600104.16us&#xff1b; 定时器第一次定时时间设为52us即半个bit的时间&#xff0c;其目的是偏移半个bit时间&#xff0c;之后的每104us采样并读取1bit数据。使得…...

《深入理解 Spring MVC 工作流程》

一、Spring MVC 架构概述 Spring MVC 是一个基于 Java 的轻量级 Web 应用框架&#xff0c;它遵循了经典的 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;将请求、响应和业务逻辑分离&#xff0c;从而构建出灵活可维护的 Web 应用程序。 在 Spring MV…...

HTML简介

知识点一 HTML 什么是HTML&#xff1f; 超文本标记语言(HyperTextMarkup Language&#xff0c;简称HTML) 怎么学HTML&#xff1f; HTML 是一门标记语言&#xff0c;标记语言由一套标记标签组成&#xff0c;学习 HTML&#xff0c;其实就是学习标签 开发工具 编辑器: Pycha…...

Linux系统Centos设置开机默认root用户

目录 一. 教程 二. 部分第三方工具配置也无效 一. 教程 使用 Linux 安装Centos系统的小伙伴大概都知道&#xff0c;我们进入系统后&#xff0c;通常都是自己设置的普通用户身份&#xff0c;而不是 root 超级管理员用户&#xff0c;导致我们在操作文件夹时往往爆出没有权限&am…...

【网络安全 | 甲方建设】双/多因素认证、TOTP原理及实现

未经许可,不得转载。 文章目录 背景双因素、多因素认证双因素认证(2FA)多因素认证(MFA)TOTP实现TOTP生成流程TOTP算法TOTP代码示例(JS)Google Authenticator总结背景 在传统的在线银行系统中,用户通常只需输入用户名和密码就可以访问自己的账户。然而,如果密码不慎泄…...

Nuxt3 动态路由URL不更改的前提下参数更新,NuxtLink不刷新不跳转,生命周期无响应解决方案

Nuxt3 动态路由URL不更改的前提下参数更新&#xff0c;NuxtLink不刷新不跳转&#xff0c;生命周期无响应解决方案 首先说明一点&#xff0c;Nuxt3 的动态路由响应机制是根据 URL 是否更改&#xff0c;参数的更改并不会触发 Router 去更新页面&#xff0c;这在 Vue3 上同样存在…...

2024华为java面经

华为2024年Java招聘面试题目可能会涵盖Java基础知识、核心技术、框架与工具、项目经验以及算法与数据结构等多个方面。以下是考的内容。 一、Java基础知识 Java中有哪些基本数据类型&#xff1f; Java为什么能够跨平台运行&#xff1f; String是基本数据类型吗&#xff1f;能…...

2021 年 9 月青少年软编等考 C 语言三级真题解析

目录 T1. 课程冲突思路分析T2. 余数相同问题思路分析T3. 生成括号思路分析T4. 广义格雷码思路分析T5. 菲波那契数列思路分析T1. 课程冲突 小 A 修了 n n n 门课程,第 i i i 门课程是从第 a i a_i ai​ 天一直上到第 b i b_i bi​ 天。 定义两门课程的冲突程度为:有几天…...

深度解析FastDFS:构建高效分布式文件存储的实战指南(下)

接上篇&#xff1a;《深度解析FastDFS&#xff1a;构建高效分布式文件存储的实战指南&#xff08;上&#xff09;》 传送门: link 文章目录 六、常用命令七、FastDFS配置详解7.1 tracker配置文件7.2 tracker目录及文件结构7.3 storage配置文件7.4 storage服务器的目录结构和文件…...

Python学习29天

二分查找 # 定义函数冒泡排序法从大到小排列 def bbble_sort(list):# i控制排序次数for i in range(len(list) - 1):# j控制每次排序比较次数for j in range(len(list) - 1 - i):if list[j] < list[j 1]:list[j], list[j 1] list[j 1], list[j] # 定义二分查找函数 def…...

Soul App创始人张璐团队携多模态大模型参加GITEX GLOBAL,展现未来社交趋势

作为中东地区规模最大、最成功的计算机通讯及消费性电子产品展,GITEX GLOBAL一直颇受全球关注,于今年迎来了第44届盛会。自诞生以来,GITEX GLOBAL始终聚焦技术驱动的创新,吸引了许多科技巨头、创新企业及投资者的参与。Soul App作为中国较早将AI技术引入社交的企业,今年首次亮相…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...