3. Bean 的配置

news2024/11/28 0:48:33
配置信息的继承

查看下面两个 Employee 的配置,其中 dept 属性是重复的:

<bean id="dept" class="com.parent.bean.Department">
	<property name="deptId" value="100"/>
	<property name="deptName" value="IT"/>
</bean>
<bean id="emp01" class="com.parent.bean.Employee">	 
	<property name="empId" value="1001"/>
	<property name="empName" value="Tom"/>
	<property name="age" value="20"/>
	<!-- 重复的属性值 -->
	<property name="dept" ref="dept"/>
</bean>
<bean id="emp02" class="com.parent.bean.Employee">
	<property name="empId" value="1002"/>
	<property name="empName" value="Jerry"/>
	<property name="age" value="25"/>
	<!-- 重复的属性值 -->
	<property name="dept" ref="dept"/>
</bean>

配置信息的继承:

<bean id="dept" class="com.parent.bean.Department">
	<property name="deptId" value="100"/>
	<property name="deptName" value="IT"/>
</bean>
<bean id="emp01" class="com.parent.bean.Employee">	 
	<property name="empId" value="1001"/>
	<property name="empName" value="Tom"/>
	<property name="age" value="20"/>
	<!-- 重复的属性值 -->
	<property name="dept" ref="dept"/>
</bean>
<!-- 以emp01作为父bean,继承后可以省略公共属性值的配置 -->
<bean id="emp02" parent="emp01">
	<property name="empId" value="1002"/>
	<property name="empName" value="Jerry"/>
	<property name="age" value="25"/>
</bean>

Spring 允许继承 bean 的配置,被继承的 bean 称为父 bean。继承这个父 bean 的 bean 称为子 bean 子 bean 从父 bean 中继承配置,包括 bean 的属性配置子 bean 也可以覆盖从父 bean 继承过来的配置。
父 bean 可以作为配置模板,也可以作为 bean 实例。若只想把父 bean 作为模板,可以设置的 abstract 属性为 true,这样 Spring 将不会实例化这个 bean。如果一个 bean 的 class 属性没有指定,则必须是抽象 bean,并不是元素里的所有属性都会被继承。比如:autowire,abstract 等。也可以忽略父 bean 的 class 属性,让子 bean 指定自己的类,而共享相同的属性配置。但此时 abstract 必须设为 true。

bean 之间的依赖

有的时候创建一个 bean 的时候需要保证另外一个 bean 也被创建,这时我们称前面的 bean 对后面的 bean 有依赖。例如:要求创建 Employee 对象的时候必须创建 Department。
这里需要注意的是依赖关系不等于引用关系,Employee 即使依赖 Department 也可以不引用它。

<bean id="emp03" class="com.parent.bean.Employee" depends-on="dept">
	<property name="empId" value="1003"/>
	<property name="empName" value="Kate"/>
	<property name="age" value="21"/>
</bean>
bean 的作用域

在 Spring 中,可以在元素的 scope 属性里设置 bean 的作用域,以决定这个 bean 是单实例的还是多实例的。
默认情况下,Spring 只为每个在 IOC 容器里声明的 bean 创建唯一一个实例,整个 IOC 容器范围内都能共享该实例:所有后续的 getBean()调用和 bean 引用都将返回这个唯一的 bean 实例。该作用域被称为 singleton,它是所有 bean 的默认作用域。
在这里插入图片描述

当 bean 的作用域为单例时,Spring 会在 IOC 容器对象创建时就创建 bean 的对象实例。而当 bean 的作用域为 prototype 时,IOC 容器在获取 bean 的实例时创建 bean 的实例对象。

bean 的生命周期
  • Spring IOC 容器可以管理 bean 的生命周期,Spring 允许在 bean 生命周期内特定的时间点执行指定的任务。
  • Spring IOC 容器对 bean 的生命周期进行管理的过程:
    • 通过构造器或工厂方法创建 bean 实例
    • 为 bean 的属性设置值和对其他 bean 的引用
    • 调用 bean 的初始化方法
    • bean 可以使用了
    • 当容器关闭时,调用 bean 的销毁方法
  • 在配置 bean 时,通过 init-method 和 destroy-method 属性为 bean 指定初始化和销毁方法:
    <bean name=“user” class=“com.bean.User” init-method=“init” destroy-method=“destroy”>
  • bean 的后置处理器
    • bean 后置处理器允许在调用初始化方法前后对 bean 进行额外的处理
    • bean 后置处理器对 IOC 容器里的所有 bean 实例逐一处理,而非单一实例。其典型应用是:检查 bean 属性的正确性或根据特定的标准更改 bean 的属性。
    • bean 后置处理器时需要实现接口:org.springframework.beans.factory.config.BeanPostProcessor。在初始化方法被调用前后,Spring 将把每个 bean 实例分别传递给上述接口的以下两个方法:postProcessBeforeInitialization(Object, String)、postProcessAfterInitialization(Object, String)
  • 添加 bean 后置处理器后 bean 的生命周期
    • ①通过构造器或工厂方法创建 bean 实例
    • ②为 bean 的属性设置值和对其他 bean 的引用
    • ③将 bean 实例传递给 bean 后置处理器的 postProcessBeforeInitialization()方法
    • ④调用 bean 的初始化方法
    • ⑤将 bean 实例传递给 bean 后置处理器的 postProcessAfterInitialization()方法
    • ⑥bean 可以使用了
    • ⑦当容器关闭时调用 bean 的销毁方法
引用外部属性文件

当 bean 的配置信息逐渐增多时,查找和修改一些 bean 的配置信息就变得愈加困难。这时可以将一部分信息提取到 bean 配置文件的外部,以 properties 格式的属性文件保存起来,同时在 bean 的配置文件中引用 properties 属性文件中的内容,从而实现一部分属性值在发生变化时仅修改 properties 属性文件即可。这种技术多用于连接数据库的基本信息的配置。
直接配置:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="user" value="root"/>
	<property name="password" value="root"/>	 
	<property name="jdbcUrl" value="jdbc:mysql:127.0.0.1:3306/test"/>
	<property name="driverClass" value="com.mysql.jdbc.Driver"/>
</bean>
使用外部的属性文件

创建 properties 属性文件

prop.userName=root 
prop.password=root 
prop.url=jdbc:mysql:127.0.0.1:3306/test
prop.driverClass=com.mysql.jdbc.Driver

从 properties 属性文件中引入属性值

<!-- 指定properties属性文件的位置 →<context:property-placeholder location="classpath:jdbc.properties"/><!-- 从properties属性文件中引入属性值 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="user" value="${prop.userName}"/>
	<property name="password" value="${prop.password}"/>
	<property name="jdbcUrl" value="${prop.url}"/>
	<property name="driverClass" value="${prop.driverClass}"/>
</bean>
自动装配

概念

  • 手动装配:以 value 或 ref 的方式明确指定属性值都是手动装配。
  • 自动装配:根据指定的装配规则,不需要明确指定,Spring 自动将匹配的属性值注入 bean 中。

装配模式

  • 根据类型自动装配:将类型匹配的 bean 作为属性注入到另一个 bean 中。若 IOC 容器中有多个与目标 bean 类型一致的 bean,Spring 将无法判定哪个 bean 最合适该属性,所以不能执行自动装配
  • 根据名称自动装配:必须将目标 bean 的名称和属性名设置的完全相同
  • 通过构造器自动装配:当 bean 中存在多个构造器时,此种自动装配方式将会很复杂。不推荐使用。
SpEL

简介
Spring Expression Language,Spring 表达式语言,简称 SpEL。支持运行时查询并可以操作对象图。和 JSP 页面上的 EL 表达式一样,SpEL 根据 JavaBean 风格的 getXxx()、setXxx()方法定义的属性访问对象图,完全符合我们熟悉的操作习惯。

基本语法
SpEL 使用#{…}作为定界符,所有在大框号中的字符都将被认为是 SpEL 表达式。

使用字面量

  • 整数:
  • 小数:
  • 科学计数法:
  • String 类型的字面量可以使用单引号或者双引号作为字符串的定界符号
    • <property name=“name” value="#{‘Chuck’}"/>
    • <property name=“name” value=’#{“Chuck”}’/>
  • Boolean:<property name=“enabled” value="#{false}"/>
  • 引用其他bean:<property name=“detp” value="#{dept}"/>
  • 引用其他 bean 的属性值:<property name=“deptName” value="#{dept.deptName}"/>
通过注解配置 bean

概述
相对于 XML 方式而言,通过注解的方式配置 bean 更加简洁和优雅,而且和 MVC 组件化开发的理念十分契合,是开发中常用的使用方式。

使用注解标识组件

  • 普通组件:@Component 标识一个受 Spring IOC 容器管理的组件
  • 持久化层组件:@Repository 标识一个受 Spring IOC 容器管理的持久化层组件
  • 业务逻辑层组件:@Service 标识一个受 Spring IOC 容器管理的业务逻辑层组件
  • 表述层控制器组件:@Controller 标识一个受 Spring IOC 容器管理的表述层控制器组件
  • 组件命名规则:
    • ①默认情况:使用组件的简单类名首字母小写后得到的字符串作为 bean 的 id(类名为HelloWorld,则在容器中的bean的id为helloWorld)
    • ②使用组件注解的 value 属性指定 bean 的 id
      注意:事实上 Spring 并没有能力识别一个组件到底是不是它所标记的类型,即使将@Respository 注解用在一个表述层控制器组件上面也不会产生任何错误,所以@Respository、@Service、@Controller 这几个注解仅仅是为了让开发人员自己明确 当前的组件扮演的角色。
扫描组件

组件被上述注解标识后还需要通过 Spring 进行扫描才能够侦测到。

  • 指定被扫描的 package
<!-- 开启注解 -->
<context:annotation-config /> 
<!-- 配置容器资源扫描的包 -->
<context:component-scan base-package="com.component"/>
  • base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包及其子包中的所有类。
  • 当需要扫描多个包时可以使用逗号分隔。
  • 如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类
  • JAR 包必须在原有 JAR 包组合的基础上再导入一个:spring-aop-4.0.0.RELEASE.jar
组件装配
  • 需求
    Controller 组件中往往需要用到 Service 组件的实例,Service 组件中往往需要用到Repository 组件的实例。Spring 可以通过注解的方式帮我们实现属性的装配。
  • 实现依据
    在指定要扫描的包时,context:component-scan 元素会自动注册一个 bean 的后置处理器:AutowiredAnnotationBeanPostProcessor 的实例。该后置处理器可以自动装配标记了@Autowired、@Resource 或@Inject 注解的属性。
  • @Autowired 注解
    ①根据类型实现自动装配。
    ②构造器、普通字段(即使是非 public)、一切具有参数的方法都可以应用@Autowired 注解
    ③默认情况下,所有使用@Autowired 注解的属性都需要被设置。当 Spring 找不到匹配的 bean 装配属性时,会抛出异常。
    ④若某一属性允许不被设置,可以设置@Autowired 注解的 required 属性为 false
    ⑤默认情况下,当 IOC 容器里存在多个类型兼容的 bean 时,Spring 会尝试匹配 bean的 id 值是否与变量名相同,如果相同则进行装配。如果 bean 的 id 值不相同,通过类型的自动装配将无法工作。此时可以在@Qualifier 注解里提供 bean的名称。Spring 甚至允许在方法的形参上标注@Qualifiter 注解以指定注入 bean 的名称。
    ⑥@Autowired 注解也可以应用在数组类型的属性上,此时 Spring 将会把所有匹配的 bean 进行自动装配。
    ⑦@Autowired 注解也可以应用在集合属性上,此时 Spring 读取该集合的类型信息,然后自动装配所有与之兼容的 bean。
    ⑧@Autowired 注解用在 java.util.Map 上时,若该 Map 的键值为 String,那么 Spring 将自动装配与值类型兼容的 bean 作为值,并以 bean 的 id 值作为键。
  • @Resource
    @Resource 注解要求提供一个 bean 名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为 bean 的名称。
  • @Inject
    @Inject 和@Autowired 注解一样也是按类型注入匹配的 bean,但没有 reqired 属性。

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

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

相关文章

#define定义宏

#define的定义范围 #define不光可以定义变量&#xff0c;常量&#xff0c;还可以定义几乎所有的东西&#xff0c;因为#define可以定义一串代码&#xff08;即宏&#xff09;&#xff0c;所以包含在代码中的东西都能被定义。 #define定义宏 定义是宏名必须于它的参数括号紧挨&am…

秋招复习篇之代码规范

目录 前言 1、变量命名 2、代码空格 1&#xff09;操作符左右一定有空格&#xff0c; 2&#xff09;分隔符&#xff08;, 和;&#xff09;前一位没有空格&#xff0c;后一位保持空格&#xff0c;例如&#xff1a; 3&#xff09;大括号和函数保持同一行&#xff0c;并有一个空格…

2024年第三届服务机器人国际会议(ICoSR 2024) | Ei、Scopus双检索

会议简介 Brief Introduction 2024年第三届服务机器人国际会议(ICoSR 2024) 会议时间&#xff1a;2024年7月26日-28日 召开地点&#xff1a;中国杭州 大会官网&#xff1a;www.iwosr.org 进入新时代&#xff0c;科技更新迭代快速发展&#xff0c;机器人不仅变得更加节能&#x…

SpringBoot+AOP+Redis 防止重复请求提交

本文项目基于以下教程的代码版本&#xff1a; https://javaxbfs.blog.csdn.net/article/details/135224261 代码仓库: springboot一些案例的整合_1: springboot一些案例的整合 1、实现步骤 2.引入依赖 我们需要redis、aop的依赖。 <dependency><groupId>org.spr…

【滑动窗口】【二分查找】C++算法:和至少为 K 的最短子数组

作者推荐 动态规划 多源路径 字典树 LeetCode2977:转换字符串的最小成本 本题涉及知识点 滑动窗口 有序向量 二分查找 LeetCode862:和至少为 K 的最短子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;找出 nums 中和至少为 k 的 最短非空子数组 &#xff0c;并返回…

5G时代的电商:超高速网络如何改变购物体验?

随着5G技术的不断发展和商业化推广&#xff0c;超高速网络正深刻地改变着人们的生活方式&#xff0c;其中最显著的之一便是电子商务领域。本文将深入探讨5G时代电商的发展趋势&#xff0c;以及超高速网络如何深刻改变用户的购物体验。 5G技术的崛起 5G技术是第五代移动通信技术…

nfs高可用部署

一、前言 为了避免nfs单点问题导致的服务不可用&#xff0c;使用以下架构实现nfs的高可用&#xff0c;keepalivedinotifyrsyncnfs&#xff0c;keepalived实现nfs的高可用&#xff0c;inotify持续监控nfs数据目录的变化&#xff0c;发生变化后通过rsync进行同步到备节点&#xf…

元旦快到了,分享一些元旦祝福模板

元旦-王安石 爆竹声中一岁除&#xff0c;春风送暖入屠苏。 千门万户曈曈日&#xff0c;总把新桃换旧符。 元旦其实也是中国的传统节日了&#xff0c;不过元旦是由中国的春节演化而来的。传统的元旦时间是正月初一&#xff0c;从王安石的诗也能看的出来&#xff0c;其实描述的…

Apache Doris (五十六): Doris Join类型 - 四种Join对比

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 Doris 支持两种物理算子,一类是…

Linux自定义shell编写

Linux自定义shell编写 一.最终版本展示1.动图展示2.代码展示 二.具体步骤1.打印提示符2.解析命令行3.分析是否是内建命令1.shell对于内建名令的处理2.cd命令3.cd函数的实现4.echo命令的实现5.export命令的实现6.内建命令函数的实现 4.创建子进程通过程序替换执行命令5.循环往复…

RabbitMQ是做什么的

rabbitMQ是做异步通讯的。用于解决同步同讯的拓展性差&#xff0c;级联失败的问题。 异步调用方式其实就是基于消息通知的方式&#xff0c;一般包含三个角色:。 消息发送者:投递消息的人&#xff0c;就是原来的调用方 消息代理:管理、暂存、转发消息&#xff0c;你可以把它理…

060:vue中markdown编辑器mavon-editor的应用示例

第060个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

Hadoop之Yarn 详细教程

1、yarn 的基本介绍和产生背景 YARN 是 Hadoop2 引入的通用的资源管理和任务调度的平台&#xff0c;可以在 YARN 上运行 MapReduce、Tez、Spark 等多种计算框架&#xff0c;只要计算框架实现了 YARN 所定义的 接口&#xff0c;都可以运行在这套通用的 Hadoop 资源管理和任务调…

兔子目标检测数据集VOC格式3900张

兔子是一类可爱的哺乳动物&#xff0c;拥有圆润的脸庞和长长的耳朵&#xff0c;身体轻盈柔软。它们通常是以温和和友善的形象出现在人们的视野中&#xff0c;因此常常成为童话故事和卡通形象中的角色。 兔子是草食性动物&#xff0c;主要以各种草本植物为食&#xff0c;包括草…

数字 IC 笔试易混淆整理

signed 扩展 比较以下4段代码&#xff0c;给出W_DATA2的结果&#xff08;十进制或16进制或二进制&#xff09;&#xff1b; wire signed [3:0] W_DATA1 4b1000; wire signed [7:0] W_DATA2; assign W_DATA2 W_DATA1; wire [3:0] W_DATA1 4b1000; wire signed [7:0] W_DA…

【Docker】添加指定用户到指定用户组

运行Docker ps命令&#xff0c;报错&#xff1a;/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied 创建docker用户组 安装docker时默认已经创建好 sudo groupadd docker添加用户加入docker用户组 此处以用户user为例 sudo usermo…

@Zabbix监控网络设备Trap接口UPDOWN关联告警配置

网络设备Trap接口UPDOWN关联告警配置 文章目录 网络设备Trap接口UPDOWN关联告警配置SNMPTrap描述1.监控平台监控项配置2.监控平台日志接收3.监控平台触发器配置4.监控平台触发器功能测试1&#xff09;告警触发2&#xff09;告警恢复 5.告警解析 SNMPTrap描述 在Zabbix中&#x…

作为铭文跨链赛道龙头,SoBit 有何突出之处?

跨链桥赛道将是铭文市场长期的发展的刚需 在比特币网络中&#xff0c;Ordinals铭文铸造的铭文总量已经超过了5100万枚&#xff0c;并累计费用收入超5028 BTC。同时&#xff0c;仅BRC-20叙事方向的市值&#xff0c;就已经超过了30亿美元&#xff0c;并且随着铭文资产种类与数量的…

Java商城 免 费 搭 建:鸿鹄云商实现多种商业模式,VR全景到SAAS,应有尽有!

鸿鹄云商 b2b2c产品概述 【b2b2c平台】&#xff0c;以传统电商行业为基石&#xff0c;鸿鹄云商支持“商家入驻平台自营”多运营模式&#xff0c;积极打造“全新市场&#xff0c;全新 模式”企业级b2b2c电商平台&#xff0c;致力干助力各行/互联网创业腾飞并获取更多的收益。从消…

『JavaScript』全面解析JavaScript中的防抖与节流技术及其应用场景

&#x1f4e3;读完这篇文章里你能收获到 理解防抖&#xff08;Debouncing&#xff09;和节流&#xff08;Throttling&#xff09;的概念&#xff1a;了解这两种性能优化技术如何帮助我们更有效地处理频繁触发的事件掌握防抖与节流的实现方法&#xff1a;学习如何在JavaScript中…