一文带你了解Spring中存入Bean和获取Bean的方式

0. Spring中的五大注解

在这里插入图片描述
上图中就是五大类注解对应的层,通过源码可以看到其他四个注解都基于@Conponent

1. 存入 Bean

Spring既然是一个包含众多工具方法的IoC容器,它是一个控制反转的容器,所以就需要将Bean对象存入到容器中,需要用的时候从容器中获取Bean对象,下面我们来介绍下存入Bean对象。

1.1 在 xml 中存入 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"xmlns:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">// 这句代码中, id 就是给 这个要注入的对象取个名字, class就是 要存入的 Bean 的类型是哪一个<bean id = "user" class="com.java.demo.User"></bean></beans>

在这里插入图片描述

1.2 通过配置 Bean 扫描路径 + 类注解 实现 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"xmlns:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!-- 通过配置扫描路径 --><content:component-scan base-package="com.java.demo"></content:component-scan></beans>

配置了 Bean 的扫描路径,只有当前目录下的类才会被扫描是否加了类注解,如果加了类注解后,就会将 所有加了类注解的类 存入到 IoC 容器中。

@Component
public class User {public void say(){System.out.println("Hello User...");}
}

类注解存Bean需要注意几点

  • 如果类名为大驼峰命名规则,那么获取 Bean 的默认名称,就是 类名首字母小写
  • 如果不满足首字母大写,第二个字母小写,那么 Bean 的名称,就是原类名,这点可以看源码知道
    在这里插入图片描述

1.3 通过配置 Bean 扫描路径 + 方法注解 实现 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"xmlns:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!-- 通过配置扫描路径 --><content:component-scan base-package="com.java.demo"></content:component-scan></beans>
public class Student {private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
@Component
public class User {@Beanpublic Student getStudent(){Student student = new Student();student.setName("张三");student.setAge(18);return student;}public void say(){System.out.println("Hello User...");}
}

在上述代码中,我们可以通过 在方法上 加上 @Bean 注解 将该方法存入到 IoC 容器中,并且可以直接获取到该对象。
在这里插入图片描述


在使用 @Bean 注解的时候,需要注意几点

  • @Bean 注解必须配合 五大类注解一块使用
  • @Bean 注解的默认命名 = 方法名称
  • 如果使用 @Bean(“xxxx”)方式,那么名称就是 xxxx, 并且 @Bean({“xxx”,“xxxxx”,“xxxxxx”}),里面可以类似和数组一样多个名称
  • 如果@Bean重命名后,那么默认的方法名就没用,获取Bean的时候就不能写默认方法名
  • 如果多个 Bean 使用相同的名称,则不会报错,只会存储第一个 Bean对象,之后相同名称的不会存入,会自动忽略

2. 获取 Bean

2.1 依赖查找(DF)

依赖查找(依赖Bean的名称),有两种方式,一种是 ApplicationContext, 一种是 BeanFactory。这两种都是容器管理对象,都可以获取到 Bean对象

2.11 ApplicationContext

public class App {public static void main(String[] args) {// 1. 获取 Spring 上下文对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 2。获取 Bean 对象Student student = (Student) context.getBean("student");System.out.println(student);}
}

2.12 BeanFactory

    public static void main(String[] args) {// 1. 得到 spring 上下文对象BeanFactory context = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));// 2. 获取 Bean 对象//Student student = (Student)context.getBean("user");Student student = (Student)context.getBean("student");System.out.println(student.toString());}

2.13 Application VS BeanFactory

ApplicationContextBeanFactory
ApplicationContext是BeanFactory的子类,其拥有更多功能(国际化支持、资源访问支持、事件传播)BeanFactory是ApplicationContext的父类
ApplicationContext加载Bean:一次性加载所有Bean对象BeanFactory加载Bean:懒加载,按需加载(使用一个加载一个)

在这里插入图片描述

2.2 依赖注入(DI)

在 spring 中实现依赖注入的常见方式有3种:

  • 1.属性注入
  • 2.setter注入
  • 3.构造方法注入

2.21 属性注入

@Controller
public class UserController {/*** 属性注入*/@Autowiredprivate UserService userService;// 此处 main方法里面,必须使用依赖查找的方式,先获取到UserControllerpublic static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");UserController userController = (UserController) context.getBean("userController");userController.userService.say();}
}

属性注入:

优点: 实现简单、使用简单,只需要在属性上加一个注解@Autowired,就不需要自己new一个对象,直接获得注入的对象。

缺点:

  1. 无法注入一个用 final 修饰的对象在这里插入图片描述
    因为在Java语法中,final修饰的对象(不可变),要么一开始就赋值,要么在构造方法里面赋值。而上述使用属性注入,注入final修饰的对象,就不符合规范,所以不行。

  1. 只能适用于 IoC 容器:如果将这些代码放到其他非IoC容器中,那么代码就会失效
  2. 设计原则:更容易违背单一原则,因为属性注入比较简单,那么可能就会在一个类中注入多个对象,这就可能不符合程序的单一职责问题。

2.22 Setter注入

@Controller
public class UserController2 {private UserService userService;/*** setter注入*/@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");UserController2 userController2 = (UserController2) context.getBean("userController2");userController2.userService.say();}}

优点:似乎没什么优点,而且比属性注入更加麻烦,要说唯一可能有用的就是,完全符合单一职责设计原则,每个 setter 只针对一个对象。Setter注入 也适用于非IoC容器
缺点:

  1. 不能注入 final 对象
    在这里插入图片描述
  2. 由于是 Setter 注入,提供了 set 方法,那么注入的对象可以随时被更改

2.23 构造方法注入(Spring4.x之后推荐的)

@Controller
public class UserController3 {private final UserService userService;/*** 构造方法注入*/// @Autowired 此处如果构造方法参数只有一个的时候,该注解可有可无public UserController3(UserService userService) {this.userService = userService;}public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");UserController3 userController3 = (UserController3) context.getBean("userController3");userController3.userService.say();}
}

优点:

  1. 可以注入 被final 修饰的对象在这里插入图片描述

  2. 注入对象不会被更改,因为是在构造方法注入的,构造方法在对象创建的时候只会创建一次

  3. 注入的对象会被完全初始化

  4. 通用性会更好,无论在 IoC容器 还是 非 IoC容器中都能用

缺点:

  1. 写法更加复杂
  2. 使用构造方法,无法解决循环依赖的问题

Spring官方推荐的是构造方法的注入,可以注入不可变对象,通用性更好;如果想要注入可变对象,那么可以使用 Setter 注入。

3. 解决同一类型多个 Bean 的报错问题

在这里插入图片描述
上述代码,可以看到报错,出现了多个同一类型的多个Bean报错,需要1个,找到了2个。如何解决呢

  • 1.@Autowired 配合 @Qualifier(value = “xxx”)一起使用,里面参数加方法名字在这里插入图片描述
  • 2.使用@Resource(name = “xxxx”)在这里插入图片描述

3. @Resource 和 @Autowired

  • 出身不同:@Resource来自于JDK,@Resource来自于Spring

  • 支持参数不同:@Resource支持更多的参数在这里插入图片描述
    @Autowired只支持一个参数设置

  • 使用上的区别:@Resource不支持构造方法的注入
    在这里插入图片描述

  • 兼容性问题:@Autowired在社区版 IDEA可能会误报;


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

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

相关文章

使用Jenkins自由风格的软件项目实现接口自动化测试持续集成

这里写目录标题 一、JOB项目配置1、添加描述2、限制项目的运行节点3、源码管理4、构建触发器5、构建步骤6、构建后操作 一、JOB项目配置 1、添加描述 可选选项可填可不填 2、限制项目的运行节点 节点中要有运行环境所需的配置 节点配置教程&#xff1a;https://blog.csdn…

回归预测 | MATLAB实现基于SVM-Adaboost支持向量机结合AdaBoost多输入单输出回归预测

回归预测 | MATLAB实现基于SVM-Adaboost支持向量机结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于SVM-Adaboost支持向量机结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于SVM-Adaboost支持向…

Spring初识(一)

一.Spring 是什么&#xff1f; 首先我们来看看官网的解释 Spring 使每个人都可以更快、更轻松、更安全地进行 Java 编程。Spring 对速度、简单性和生产力的关注使其成为 世界上最受欢迎的 Java框架。 这里我简单的说明一下什么是spring? 我们通常所说的 Spring 指的是 Sprin…

[JavaScript游戏开发] 2D二维地图绘制、人物移动、障碍检测

系列文章目录 第一章 2D二维地图绘制、人物移动、障碍检测 第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示) 文章目录 系列文章目录前言一、列计划1.1、目标1.2、步骤 二、使用步骤2.1、准备素材(图片)&#xff1a;草坪、人物(熊猫)、障碍(石头)2.2、初…

Python对Excel不同的行分别复制不同的次数

本文介绍基于Python语言&#xff0c;读取Excel表格文件数据&#xff0c;并将其中符合我们特定要求的那一行加以复制指定的次数&#xff0c;而不符合要求的那一行则不复制&#xff1b;并将所得结果保存为新的Excel表格文件的方法。 这里需要说明&#xff0c;在我们之前的文章Pyt…

〖Python网络爬虫实战㉜〗- 协程基本原理

订阅:新手可以订阅我的其他专栏。免费阶段订阅量1000+ python项目实战 Python编程基础教程系列(零基础小白搬砖逆袭) 说明:本专栏持续更新中,订阅本专栏前必读关于专栏〖Python网络爬虫实战〗转为付费专栏的订阅说明作者:爱吃饼干的小白鼠…

【Ubuntu报错】command not found: nmcli

如果在你的Linux系统上运行nmcli时出现"command not found"错误&#xff0c;这可能意味着nmcli命令行工具没有安装或没有在系统的环境变量中找到。 nmcli命令通常随着NetworkManager软件包一起提供。为了解决这个问题&#xff0c;你可以尝试以下步骤&#xff1a; 如…

SpringBoot Cache 整合 Redis 缓存框架

文章目录 引入依赖配置 Redis启动类注解注解开发CacheableCachePutCacheEvict 注解属性cacheNames/valuekeykeyGeneratorconditionunlesscacheManagersync SpEL 表达式 SpringBoot 提供了 SpringBootCache 框架作为 SpringBoot 的缓存统一框架&#xff0c;使用 SpringBootCache…

php连接上mysql数据库该的配置方法

用mysql官方的管理工具workbench&#xff1a; 打开导出界面后&#xff0c;下一步&#xff0c;选择csv格式&#xff0c;导出后excel就能打开了 如果你需要在程序代码中导出&#xff0c;需要找到对应代码的excel处理库。 如php 的 phpExcel( 最新版已更名为 phpoffice/phpspread…

selenium WebDriver 中的几种等待--sleep(),implicitly_wait(),WebDriverWait()

目录 强制等待:sleep() 隐式等待:implicitly_wait() 显示等待:WebDriverWait() 与until()或者until_not()方法结合使用 WebDriverWait与expected_conditions结合使用 显示等待,自定义等待条件 强制等待:sleep() import time sleep(5) #等待5秒 设置固定休眠时间&#x…

14matlab数理统计 多项式的求根和根据根求多项式(matlab程序)

1.简述 分享一下通过多种不同的方法计算多项式的根。 数值根 使用代换法求根 特定区间内的根 符号根 数值根 roots 函数用于计算系数向量表示的单变量多项式的根。 例如&#xff0c;创建一个向量以表示多项式 x2−x−6&#xff0c;然后计算多项式的根。 p [1 -1 -6]; r …

Prometheus节点监控及hadoop集群监控

背景:我司长期苦于CM6.3后收费问题,这次领导痛下决心,决定要自己开发一套大数据管理平台,监控就是其中一部分,本文主要阐述,话不多说,先看效果。 1.监控组件Prometheus 1.1上传Prometheus包 [root@bigdb01 ~]# rsync root@172.16.1.247/data/fan/install/native/09.…

uni.app如何检测小程序版本更新以及上线后如何关闭全局打印

uni.app如何检测小程序版本更新以及上线后如何关闭全局打印 检测小程序版本更新关闭全局打印 检测小程序版本更新 App.vue 入口文件中 添加如下代码 //检测小程序版本是否更新const updateManager wx.getUpdateManager()updateManager.onCheckForUpdate(function(res) {// 请求…

DuiLib中的list控件以及ListContainerElement控件

文章目录 前言1、创建list控件2、创建 ListContainerElement 元素&#xff0c;并添加到 List 控件中,这里的ListContainerElement用xml来表示3、在 ListContainerElement 元素中添加子控件 1、List控件2、ListContainerElement控件 前言 在 Duilib 中&#xff0c;List 控件用于…

【批量将视频转为图像序列】

批量将视频转为图像序列 代码如下&#xff0c;代码中带有解释&#xff1a; # 导入所需要的库 import cv2 import os import numpy as np# 多个视频所在的路径 datasets_path ["/home/y/Code/数据集/1/007f.mp4","/home/y/Code/数据集/1/05f.mp4","/…

UI界面中的图标设计趋势与最佳实践

作为UI设计师&#xff0c;在日常的工作中&#xff0c;避免不了做图标规范。今天跟大家聊一聊&#xff0c;UI设计中的图标设计。 规范的重要性不用多说了&#xff0c;没有规范多个设计师绘制的图标会有很多差异&#xff0c;描边粗细、角度、圆角度等等。今天的文章和大家聊一下…

ChatGPT 的局限性是什么?

ChatGPT 的局限性是什么&#xff1f; 尽管看起来非常令人印象深刻&#xff0c;但 ChatGPT 仍然存在局限性。此类限制包括无法回答以特定方式措辞的问题&#xff0c;因为它需要重新措辞才能理解输入的问题。更大的限制是它提供的响应缺乏质量 - 有时听起来似是而非&#xff0c;…

leetcode303. 区域和检索 - 数组不可变 前缀和

https://leetcode.cn/problems/range-sum-query-immutable/ 给定一个整数数组 nums&#xff0c;处理以下类型的多个查询: 计算索引 left 和 right &#xff08;包含 left 和 right&#xff09;之间的 nums 元素的 和 &#xff0c;其中 left < right 实现 NumArray 类&…

Stable Diffusion - 编辑生成 (OpenPose Editor) 相同人物姿势的图像

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131818943 OpenPose Editor 是 Stable Diffusion 的扩展插件&#xff0c;可以自定义人物的姿势和表情&#xff0c;以及生成深度、法线和边缘图等信…

vue 集成tinymce2实现图片,视频以及文件的上传

vue 集成tinymce2实现图片&#xff0c;视频以及文件的上传 1. 安装插件 &#xff08;1&#xff09;安装tinymce npm install tinymce -S &#xff08;2&#xff09;安装tinymce-vue npm install tinymce/tinymce-vue3.0.1 -S 2. 复制静态文件到public目录 资源下载路径&…