【Spring】——Spring简单 读和取

article/2025/10/2 3:16:15

前言 

❤️❤️❤️Spring专栏更新中,各位大佬觉得写得不错,支持一下,感谢了!❤️❤️❤️

Spring_冷兮雪的博客-CSDN博客

上期我们讲解了Spring的创建与使用,发现 将Bean 注册到容器 这一步中,如果Bean对象过多,在注册到容器时,我们有几个Bean对象就需要几行注册,在实际开发中这是非常麻烦的,我们需要有更简单的方法去实现这一过程,这便是本篇文章的主题——Spring简单 读和取。

 一、存储Bean对象[读]🍭

在Spring中我们可以使用注解存储和读取Bean对象,而其中我们有两种注解类型可以实现这个功能。

  1. 类注解:@Controller(控制器存储)、@Service(服务存储) 、@Repository(仓库存储)、@Component(组件存储)、@Configuration(配置存储)。
  2. 法注解:@Bean。

1、配置扫描路径🍉

但是在使用注解去进行存储和读取Bean对象之前,我们还需要进行配置扫描路径。在spring-config.xml中添加如下配置:

<?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.demo.component"></content:component-scan>
</beans>

 2、类注解🍉

Ⅰ、@Controller(控制器存储)🍓

 ArticleController类:

package com.demo.component;import org.springframework.stereotype.Controller;@Controller// 将对象存储到 Spring 中
public class ArticleController {public String sayHi(){return "Hello word";}
}

还是使用上篇讲的方法 去读取Bean对象:

import com.demo.component.ArticleController;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;public class App {public static void main(String[] args) {//1、获取spring对象ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");//2、从Spring中取出Bean对象ArticleController articleController=(ArticleController) context.getBean("articleController");//3、使用Bean(可选)System.out.println(articleController.sayHi());//输出Hello word}
}

Ⅱ、@Service(服务存储)🍓

 ArticleController类:

package com.demo.component;import org.springframework.stereotype.Service;@Service// 将对象存储到 Spring 中
public class ArticleController {public String sayHi(){return "Hello word";}
}

还是使用上篇讲的方法 去读取Bean对象:

import com.demo.component.ArticleController;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;public class App {public static void main(String[] args) {//1、获取spring对象ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");//2、从Spring中取出Bean对象ArticleController articleController=(ArticleController) context.getBean("articleController");//3、使用Bean(可选)System.out.println(articleController.sayHi());//输出Hello word}
}

Ⅲ、@Repository(仓库存储)🍓

 ArticleController类:

package com.demo.component;import org.springframework.stereotype.Repository;@Repository// 将对象存储到 Spring 中
public class ArticleController {public String sayHi(){return "Hello word";}
}

还是使用上篇讲的方法 去读取Bean对象:

import com.demo.component.ArticleController;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;public class App {public static void main(String[] args) {//1、获取spring对象ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");//2、从Spring中取出Bean对象ArticleController articleController=(ArticleController) context.getBean("articleController");//3、使用Bean(可选)System.out.println(articleController.sayHi());//输出Hello word}
}

Ⅳ、@Component(组件存储)🍓

 ArticleController类:

package com.demo.component;import org.springframework.stereotype.Component;@Component// 将对象存储到 Spring 中
public class ArticleController {public String sayHi(){return "Hello word";}
}

还是使用上篇讲的方法 去读取Bean对象:

import com.demo.component.ArticleController;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;public class App {public static void main(String[] args) {//1、获取spring对象ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");//2、从Spring中取出Bean对象ArticleController articleController=(ArticleController) context.getBean("articleController");//3、使用Bean(可选)System.out.println(articleController.sayHi());//输出Hello word}
}

Ⅴ、@Configuration(配置存储)🍓

package com.demo.component;import org.springframework.context.annotation.Configuration;@Configuration// 将对象存储到 Spring 中
public class ArticleController {public String sayHi(){return "Hello word";}
}

还是使用上篇讲的方法 去读取Bean对象:

import com.demo.component.ArticleController;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;public class App {public static void main(String[] args) {//1、获取spring对象ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");//2、从Spring中取出Bean对象ArticleController articleController=(ArticleController) context.getBean("articleController");//3、使用Bean(可选)System.out.println(articleController.sayHi());//输出Hello word}
}

大家一路看下来,可能会吐槽一下:为什么全都是一样的代码啊?这有什么区别啊😂!

 为什么有这么多类注解?🍓

Spring框架有很多类注解是为了让开发者以更简洁、方便的方式来定义各种不同类型的Bean(如控制器、服务、存储库等),并且能够更容易地使用Spring的各种功能(如事务管理、缓存、安全性等)。虽然Spring框架中的注解很多,但 大多数都有特定的功能和用途,使得开发者可以根据需求选择合适的注解来使用,也可以让程序员看到类注解之后,就能直接了解当前类的用途,比如: 
  • @Controller(控制器):业务逻辑层,用来控制用户的行为,它用来检查用户参数的有效性。
  • @Servie(服务): 服务层,调用持久化类实现相应的功能。[不直接和数据库交互的,它类似于控制中心]
  • @Repository (仓库):持久层,是直接和数据库进行交互的。通常每一个表都会对应一个 @Repository。
  • @Configuration(配置):配置层,是用来配置当前项目的一些信息。
  • @Component (组件) : 公共工具类,提供某些公共方法。
程序的工程分层,调用流程如下:

五大类注解的联系🍓

直接看@Controller 、@Service 、@Repository 、@Configuration 等注解的源码:

@Service

@Repository

我们可以发现这些注解里面都有⼀个注解 @Component,说明它们是属于 @Component 的,是@Component的“子类”(其他源码也都类似,大家可以自行去查看查看他们的源码,理解更深刻哦!)。

3、Bean 的命名规则🍉

连续按两下 Shift 进行搜索或者通过下图方式去打开搜索框

 在 Classes中搜索 BeanName ,打开我红色框选择的类,

 划到最下面:

 我们就找到了Bean对象的命名方法,它使用的是 JDK Introspector 中的 decapitalize 方法,源码如下:

public static String decapitalize(String name) {if (name == null || name.length() == 0) {return name;}// 如果第⼀个字⺟和第⼆个字⺟都为⼤写的情况,是把 bean 的⾸字⺟也⼤写存储了if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&Character.isUpperCase(name.charAt(0))) {return name;}// 否则就将⾸字⺟⼩写char chars[] = name.toCharArray();chars[0] = Character.toLowerCase(chars[0]);return new String(chars);}

 看源码,可以发现获取Bean时 ,Bean的命名只有两种:

  • 首字母和第二个字母都非大写,首字母小写来获取 Bean,
  • 首字母和第二个字母都是大写,那么直接使用原 Bean 名来获取

 类名为:ArticleController

正确命名方法:

错误命名方法:

 类名为:AController

 正确命名方法: 

错误命名方法:

4、方法注解Bean🍉

类注解是添加到某个类上的,而方法注解是放到某个方法上的。

Ⅰ、方法注解要配合类注解使用🍓

Bean注解需要配合五大类注解使用。
ArticleController
package com.demo.component;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component// 将对象存储到 Spring 中
public class ArticleController {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "ArticleController{" +"id=" + id +", name='" + name + '\'' +'}';}@Bean//方法注解public ArticleController acSet(){ArticleController articleController=new ArticleController();articleController.setId(1);articleController.setName("java");return articleController;}
}

使用ArticleController中的acSet方法

import com.demo.component.ArticleController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {//1、获取spring对象ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");//2、从Spring中取出Bean对象ArticleController articleController=(ArticleController) context.getBean("acSet");//命名规则和获取Bean一样//3、使用Bean(可选)System.out.println(articleController);}
}

当我们把acSet方法的@Component注解删除时,就会报错:

 因此,在使用Bean注解时需要配合使用五大类注解,才能将对象正常的存储到 Spring 容器中

Ⅱ、重命名 Bean🍓

可以通过设置 name 属性给 Bean 对象进行重命名操作。

 将acSet方法重命名为ac,并运行代码:

我们可以注意到重命名的name名是使用大括号进行存储,其实这就是一个数组,一个 bean 可以有多个名字。

aS:

import com.demo.component.ArticleController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {//1、获取spring对象ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");//2、从Spring中取出Bean对象ArticleController articleController=(ArticleController) context.getBean("aS");//3、使用Bean(可选)System.out.println(articleController);//输出:ArticleController{id=1, name='java'}}
}

但是需要注意的是,如果进行了 重命名 原类名就无法再进行获取方法了!

二、获取 Bean 对象(对象装配)[取]🍭

获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注入。

1、依赖注入的常见方式 🍉

对象装配(对象注入)的实现方法以下 3 种:
  1. 属性注入
  2. 构造方法注入
  3. Setter 注入

 刚刚好这里有一篇有关Spring依赖注入的文章,写得很好,我就不重复造轮子了。

面试突击77:Spring 依赖注入有几种?各有什么优缺点? - 掘金 (juejin.cn)

Ⅰ、三种注入优缺点分析🍓

  1. 属性注入的优点是简洁,使同方便;缺点是只能用于 IoC 容器,如果是非 IoC 容器不可用,并且只有在使用的时候才会出现 NPE(空指针异常)。
  2. 构造⽅法注入是 Spring 推荐的注入方式,它的缺点是如果有多个注⼊会显得比较臃肿,但出现这种情况你应该考虑一下当前类是否符合程序的单一职责的设计模式了,它的优点是通用性,在使用之前⼀定能把保证注⼊的类不为空。
  3. Setter 方式是 Spring 前期版本推荐的注入方式,但通用性不如构造方法,所有 Spring 现版本已经推荐使用构造方法注入的方式来进行类注入了。

2、@Resource:另一种注入关键字🍉

在进行类注入时,除了可以使用 @Autowired 关键字之外,我们还可以使用 @Resource 进行注入

@Autowired 和 @Resource 的区别:

  • 出身不同:@Autowired 来自于 Spring,而@Resource 来自于 JDK 的注解;
  • 使用时设置的参数不同:相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如 name 设置,根据名称获取 Bean。
  • @Autowired 可用于 Setter 注入、构造函数注入和属性注入,而@Resource 只能用于 Setter 注入和属性注入,不能用于构造函数注入。

 可以看到@Resource是JDK自带的方法:

构造函数注入时,@Resource 会报错:

 其实在官方文档中并没有明确指出为什么构造方法不可以使用@Resource 可能是官方类加载顺序的问题或者循环引用的问题。(可以评论区讨论,给出你的看法)

3、同一类型多个 @Bean 报错🍉

User

package com.demo.component;public class User {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "ArticleController{" +"id=" + id +", name='" + name + '\'' +'}';}
}

 Users

package com.demo.component;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class Users {@Beanpublic User user1() {User user = new User();user.setId(1);user.setName("Java");return user;}@Beanpublic User user2() {User user = new User();user.setId(2);user.setName("MySQL");return user;}
}

UserController 

package com.demo.Controller;import com.demo.component.User;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller
public class UserController {@Resourceprivate User user;public User getUser(){return user;}
}

运行APP 

 就可以看到 没有唯一Bean定义 异常

同一类型多个 Bean 报错处理 🍓

解决同一个类型,多个 bean 的解决方案有以下两个:
  • 使用@Resource(name="user1") 定义。
  • 使用@Qualifier 注解定义名称。

 使用@Resource(name="user1")

 使用@Qualifier 注解定义名称


http://chatgpt.dhexx.cn/article/GddVqaeW.shtml

相关文章

读取Spring配置文件的方法(Spring读取资源文件)

大厂必备&#xff01;读取spring配置文件的两种方法,需要的朋友可以参考下。 第一种&#xff1a; 1.spring配置文件 2.读取属性方法 第二种&#xff1a; 直接读取方式: 通过spring配置方式读取&#xff1a; spring bean配置: // 编辑不易&#xff0c;spring框架系列的快要更…

php如何将时间戳,PHP如何将时间戳转换日期

PHP如何将时间戳转换日期 在php中可以使用“date()”函数将时间戳转换日期&#xff0c;该函数用于格式化一个本地时间日期&#xff0c;其语法是“date($format,$timestamp)”&#xff0c;其参数format表示日期格式&#xff0c;参数timestamp表示要格式化的时间戳。 代码实例&am…

php 时间戳 24小时制,php如何将时间戳转换成小时制

php将时间戳转换成小时制的方法&#xff1a;【date("Y/m/d H:i:s",1446634507)】。date()函数可以把时间戳格式化为可读性更好的日期和时间。 php将时间戳转换称24小时制 (推荐教程&#xff1a;php视频教程)date("Y/m/d H:i:s",1446634507) //2015/11/04 1…

php时间戳转换日期24,php时间戳怎么转换回日期

在php中&#xff0c;可以使用date()函数来将时间戳转换回日期格式。date()函数可把时间戳格式化为可读性更好的日期和时间格式&#xff0c;语法“date (format,时间戳)”&#xff1b;format参数规定转换后的时间戳格式&#xff0c;例“Y-m-d H:i:s”。 本教程操作环境&#xff…

php里日期转为时间戳_php时间戳与日期的转换

php时间戳与日期的转换 大家也许对PHP时间戳已经有所了解&#xff0c;那么我们如何应用它来获取具体的日期呢&#xff1f;我们今天来为大家介绍一下PHP时间戳获取当前时期的具体方式。 实现功能&#xff1a;获取某个日期的时间戳&#xff0c;或获取某个时间的PHP时间戳。 strto…

html 时间戳转换年月日,时间戳与日期的转换方法

php怎么将指定日期转换为时间戳 date(Y-m-d H:i:s, 1156219870); UNIX时间戳转换为日期用函数: date() 一般形式:date(Y-m-d H:i:s, 1156219870); 日期转换为UNIX时间戳用函数:strtotime() 一般形式:strtotime(2010-03-24 08:15:42); js 中日期 转换成时间戳 例如2013-08-…

常用的计算机C语言,计算机c语言基础知识

计算机c语言基础知识 C语言程序设计是高效计算机专业学生必修的一门基础课程&#xff0c;那么你对计算机c语言了解多少呢?下面是小编整理的计算机c语言基础知识&#xff0c;欢迎大家阅读参考。 计算机c语言的特性 C语言是世界上最流行、使用最广泛的高级程序设计语言之一。在操…

C语言基础知识总结

本文的目的是记录平时工作学习过程中学习到的C语言知识&#xff0c;由于单独一篇文章记录的话可能篇幅过少&#xff0c;因此置顶此文用作此用处&#xff0c;本文从2017-12-16开始记录&#xff0c;后续新增内容不单独列出时间&#xff0c;在MarkEditor中有相应的版本记录。 文件…

【必读】C语言基础知识大全

C语言程序的结构认识 用一个简单的c程序例子&#xff0c;介绍c语言的基本构成、格式、以及良好的书写风格&#xff0c;使小伙伴对c语言有个初步认识。 例1&#xff1a;计算两个整数之和的c程序&#xff1a; #include main() { int a,b,sum; /*定义变量a,b&#xff0c;sum为整…

C语言基础知识概况

一、什么是C语言 就如人的语言分汉语英语&#xff0c;作用是实现人与人之间的交流相同。C语言是一门计算机语言。实现人与计算机交互的一种语言。C语言是一门广泛用于底层开发的编程语言 计算机的结构自上而下大概分为以下几层 应用软件QQ、网盘用户操作系统windows、Linux硬…

c语言基础知识 入门必看(保姆级教学)

&#x1f353;个人主页&#xff1a;bit.. &#x1f352;系列专栏&#xff1a;Linux(Ubuntu)入门必看 C语言刷题 C语言基础 1.什么是C语言&#xff1f;为什么要学好C语言&#xff1f; 这是2022年球程序员使用计算机语言的排名&#xff1a;我们可以很清楚的看的c语言和c在将…

C语言基础知识入门(大全详解)

一、C语言基础知识入门 C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好&#xff0c;可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言&#xff0c;所以说学习C语…

单片机C语言基础知识篇

本人是一名在校的即将大四的物联网专业学生&#xff0c;暑假期间无聊&#xff0c;想写一些东西&#xff0c;来记录之前学过的一些单片机的基础知识&#xff0c;由于记纸质笔记太过低效率了&#xff0c;而且也不看&#xff0c;所以想学着写博客来记录。后续会不定期推出Arduino篇…

C语言基础知识总结大全(建议收藏)

前言&#xff1a;C语言是当代人学习及生活中的必备基础知识&#xff0c;应用十分广泛&#xff0c;下面为大家带来C语言基础知识梳理总结&#xff0c;C语言零基础入门绝对不是天方夜谭&#xff01; 1 算法结构 一、顺序结构、选择结构、循环结构&#xff1b;二、循环结构又分为…

c语言基础知识点字母和含义,大学c语言必背基础知识_c语言基础知识大全

描述 对于刚学计算机编程的同学来说,没一个编程知识都觉得很重要,其实不是的。下面小编为大家整理了相关大学c语言必背基础知识,希望大家喜欢。 大学c语言必背基础知识 举例说明: printf(“-”,123 ); 第二部分有三位,大于指定的两位,原样输出123 printf(“]”,123 );…

【C语言】C语言中基础操作符详细讲解

接着上次的C语言基础知识梳理&#xff0c;让我们来简单了解一下C语言里的操作符 目录 整数的二进制表示形式 算术操作符 移位操作符 位操作符 赋值操作符 单目操作符 关系操作符 逻辑运算符 条件操作符-三目操作符 下标引用、函数调用、结构成员访问操作符 隐式类型…

代理模式的理解?代理模式的应用场景?

说说你对代理模式的理解&#xff1f;应用场景&#xff1f; 一、是什么 代理模式&#xff08;Proxy Pattern&#xff09;是为一个对象提供一个代用品或占位符&#xff0c;以便控制对它的访问 代理模式的关键是&#xff0c;当客户不方便直接访问一个对象或者不满足需要时&…

设计模式 —— 代理模式

目录 一、代理模式的基本介绍 二、静态代理 三、动态代理 3.1 动态代理模式的基本介绍 四、Cglib 代理 4.1 Cglib 代理模式的基本介绍 五、几种常见的代理模式介绍— 几种变体 一、代理模式的基本介绍 代理模式&#xff1a;为一个对象提供一个替身&#xff0c;以控制对…

Spring:代理模式

一、概述 代理模式分为静态代理以及动态代理&#xff0c;属于23中设计模式之一。动态代理是SpringAop的底层。代理的概念如下图所示&#xff1a; 二、 静态代理 上图角色分析&#xff1a; 抽象角色&#xff1a;一般会使用接口或者抽象类来解决真是角色&#xff1a;被代理的角色…

什么是代理模式,如何写一个代理模式

什么是代理模式 代理模式分为静态代理模式&#xff0c;和动态代理模式&#xff0c;代理模式就是创建一个代理对象&#xff0c;由代理对象来接管原对象的引用,静态代理模式需要让代理类和被代理的类实现同一个接口&#xff0c;通过代理类中定义的构造方法将被代理的对象作为参数…