Spring中Bean对象的存储与读取

这篇具有很好参考价值的文章主要介绍了Spring中Bean对象的存储与读取。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

创建 Maven 项目

Spring中Bean对象的存储与读取,spring,java,后端

添加 Spring 框架支持

在项目的 pom.xml 中添加 Spring 支持
如何选定版本环境:打开官网,点击github图标
Spring中Bean对象的存储与读取,spring,java,后端
jdk8最后一个Spring版本是5.3.x,Spring6.0.x最低需要jdk17
Spring中Bean对象的存储与读取,spring,java,后端

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.3.31</version>
        </dependency>
</dependencies>

Spring中Bean对象的存储与读取,spring,java,后端

版本冲突问题Maven自己处理
version : 可以选择带有 RELEASE结尾或者纯数字结尾,这样的版本更稳定

添加一个启动类

项目下创建一个main方法的启动类
Spring中Bean对象的存储与读取,spring,java,后端

存储 Bean 对象

  1. 存储 Bean 之前,要先有 Bean 才行
    Spring中Bean对象的存储与读取,spring,java,后端
  2. 将创建的 Bean 注册到 Spring 容器中
    这里并非实际意义上的存储,而是类似于交给 IoC 容器进行托管
    Spring中Bean对象的存储与读取,spring,java,后端
    在 resources 目录下添加 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
  1. 从 Spring 中取出 bean 对象
    取 bean 需要先得到 Spring 对象(Spring上下文)
    Spring中Bean对象的存储与读取,spring,java,后端
    获取并使用 Bean 对象,分为以下3步
  • 获取Spring上下文
  • 上下文获取 Bean
  • 使用 Bean

如果获取多个 Bean 的话,重复以上2,3步骤

两种方式获取Spring 上下文对比

Spring 上下文可以使用 ApplicationContext 或者 BeanFactory获取

ApplicationContext顶层接口

ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

Spring中Bean对象的存储与读取,spring,java,后端

BeanFactory顶层接口

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

Spring中Bean对象的存储与读取,spring,java,后端
继承关系
Spring中Bean对象的存储与读取,spring,java,后端
ApplicationContext 和 BeanFactory 效果是一样的,BeanFactory 属于 ApplicationContext 子类,它们区别如下

  • 继承角度:Spring 容器有两个顶级接口:BeanFactory 和 ApplicationContext

  • 其中 BeanFactory 提供了基础的访问容器的能力,而 ApplicationContext 属于 BeanFactory 的子类,除了 BeanFactory 的所有功能外,它还拥有独特的特性,添加了对国际化的支持、资源访问的支持、以及事件传播等方面的支持

  • 性能角度:ApplicationContext 是一次性加载并初始化所有的 Bean 对象「更方便」;BeanFactory 是按需加载并初始化「更轻量」

    ClassPathXmlApplicationContext 属于 ApplicationContext 的子类,拥有 ApplicationContext 的所有功能是通过 xml 的配置来获取所有的 Bean 容器的

获取指定的 Bean 对象

ApplicationContext context = new ClassPathXmlApplicationContext("Spring-config.xml");
        User user = (User) context.getBean("user");
        user.sayHi();
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("Spring-config.xml"));
        User user1 = (User) beanFactory.getBean("user");
        user1.sayHi();


// 运行结果
你好
你好

注意事项

Bean 的 id 要一一对应

<beans>
        <bean id="user" class="Beans.User"></bean>
</beans>
User user = (User) context.getBean("user");
User user1 = (User) beanFactory.getBean("user");

getBean 方法的更多用法

getBean() 方法很多重载,我们也可以使用其他方法来获取 Bean 对象

先看一下 getBean() 源码

Spring中Bean对象的存储与读取,spring,java,后端

getBean(String, Class): 先根据 id 匹配,再根据Class匹配

当有两个相同 id 的时候利用此方法查询会 报错Nouni

get(Class, String): 先根据Class匹配,再根据 id 匹配

当有两个的Bean,利用此方法,则会 报错Nouni

ApplicationContext context = new ClassPathXmlApplicationContext("Spring-config.xml");
User user = context.getBean(User.class);

User user1 = context.getBean("user1", User.class);

二者的区别

当有多个重复的对象被注册到 Bean 中的时候,只能通过 id属性 来获取

Spring中Bean对象的存储与读取,spring,java,后端

<beans>
        <bean id="user" class="Beans.User"></bean>
        <bean id="user1" class="Beans.User"></bean>
        <bean id="user2" class="Beans.User"></bean>
</beans>

如果继续使用 context.getBean(User.class) 就会报错。应该搭配 id 一起使用
Spring中Bean对象的存储与读取,spring,java,后端

总结Spring使用流程

  1. 操作容器之前,先要有容器
  2. 存对象
    1. 创建 Bean「普通类」
    2. 将 Bean 注册「配置」到 Spring-config.xml 中
  3. 取对象
    1. 得到 Spring 上下文,并读取到 Spring 的配置文件
    2. 获取某一个 Bean 对象
    3. 使用 Bean 对象
      Spring中Bean对象的存储与读取,spring,java,后端

配置扫描路径配合注解进行存储Bean对象

在上述操作过程中,我们发现存储对象并没有想象中的那么 简单,所以就有了更简单的操作 Bean对象 的方法
Spring 更简单的存储对象和读取对象核心是使用注解

之前我们还需要在 Spring 的配置文件 spring-config.xml 中添加一行 bean 注册内容才行

Spring中Bean对象的存储与读取,spring,java,后端

因此 Spring 中为了方便注册,我们只需要配置一个存储对象的扫描包即可「目录中的所有 Bean 被添加注解后都会被注册到 Spring 容器中」

配置扫描路径代码模板

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

对比之前的 Spring-config.xml 发现多了标红的两行,这两行就是注册扫描的包

Spring中Bean对象的存储与读取,spring,java,后端

也就是说,即使添加了注解,如果不是在配置的扫描报下的类对象,也是不能被存储的 Spring 中的

五大类注解

想把扫描包中的 Bean 添加到 Spring,由两类注解类型可以实现

  1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration
  2. 方法注解:@Bean「必须结合类注解才能起效」

这么多注解的原因

我们发现它们的功能是一样的,都能达到 添加注解注册Bean 的功能,那么为何还要有这么多注解类型呢?

这就和每个省市都有自己的车牌号一样。全国的各个地区买的相同类型的车都是一样的,但是车牌号却不同:湖北的车有鄂A:武汉的车;鄂B:黄石的车;鄂C:十堰的车。。。这样做的好处就是节约了车牌号以外还可以查看车辆的归属地方便车管局管理。

那么为什么需要这么多的类注解也是一样的原因,就是让程序员看到类注解之后就能直接了解当前类的用途

  • @Controller:业务逻辑层
  • @Service:服务层
  • @Repository:持久层
  • @Configuration:配置层

程序的工程分层调用流程如下:

Spring中Bean对象的存储与读取,spring,java,后端

@Component是其它注解的父类

Spring中Bean对象的存储与读取,spring,java,后端
发现这 4个 注解里都有一个注解 @Component,说明他们本身就是属于 @Component子类

在看 @Component的源码
Spring中Bean对象的存储与读取,spring,java,后端
源码溯源就到此为止了,只需要了解它们四个实现了@Component接口即可

Bean 的命名源码

通过注解注册的bean名称有自己的一套默认规则:

  1. 第一第二首字母是大写的话就是原类名
  2. 其余是小驼峰方式命名
    Spring中Bean对象的存储与读取,spring,java,后端
public static String decapitalize(String name) {
    if (name == null || name.length() == 0) {
        return name;
    }
  	// 如果类名长度大于1,并且前俩字母都是大写就直接返回原类名
    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要搭配类注解一起使用才可以将方法存储到 Spring 中

model层

package app.model;

public class User {
    private Integer id;
    private String userName;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

service层

package app.service;

import app.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void doUserService() {
        System.out.println("doUserService.");
    }

    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setUserName("张三");
        user.setAge(18);
        return user;
    }
}

controller层

package app.controller;

import app.model.User;
import app.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;

// 也可以通过 xml 中 bean 标签注册
@Controller
public class UserController {
	@Autowired
    private UserService userService;

    public void doUserController() {
        System.out.println("doUserController.");
    }

	@Bean
    public User getUser() {
        return userService.getUser();
    }
}

获取@Bean对象:bean名称采取的是方法名而非类名

// 1.获取 Spring 上下文
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config.xml");
// @Bean方法注解
User user = beanFactory.getBean("getUser", User.class);

重命名 Bean

同一项目下类名一般不会出现重复但方法名有意外情况

  1. 不同类名出现同一个方法名
    Spring中Bean对象的存储与读取,spring,java,后端
  2. 同一类中出现方法重载
    此时如果调用会报错,因为@Bean注解无法添加参数

查看 @Bean 源码会发现 name 是一个数组,因此可以填入很多bean的名称。但一般一个就够。
Spring中Bean对象的存储与读取,spring,java,后端
3种方式给Bean重命名。重命名之后就不能通过方法名获取Bean对象了
Spring中Bean对象的存储与读取,spring,java,后端

获取Bean对象(对象装配)

回顾之前在存储bean对象之后是如何获取的

  1. new
  2. 先得到Spring上下文,再通过getBean获取
  3. 更简单的获取方式:对象注入

这里就讲解一下对象注入
对象装配:获取 Bean 对象
对象注入:把对象取出来放在某个类中

对象注入有 3 种方法

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

属性注入

@Autowired: 现根据类型查找再根据名称查找。所以bean的名称随意给都可以,这里按照标准给的是 userService
Spring中Bean对象的存储与读取,spring,java,后端
优点:写法简单
缺点:

  1. 功能缺陷:不支持final修饰
  2. 通用性问题:只适用于IoC容器,非IoC容器无法使用
  3. 更容易违背单一设计原则(因为使用简单,所以滥用风险更大)

Setter 注入

Spring中Bean对象的存储与读取,spring,java,后端
优点:符合单一设计原则
缺点:

  1. 功能缺陷:不能诸如一个不可变对象【不能被final修饰】
  2. 注入对象可能会被改变

构造方法注入

final不加也可以,对于专业版IDEA会提示进行final修饰
Spring中Bean对象的存储与读取,spring,java,后端
当当前类中只有一个构造方法的时候可以省略@Autowired
优点:

  1. 支持final修饰注入不可变对象
  2. 注入对象不会被更改
  3. 完全初始化
  4. 通用性更好

另外一种对象装配的关键字:@Resource

仅支持两种装配方式,不支持构造方法注入。用法和@Autowired一样

  1. 属性注入
  2. Setter注入

@Resource支持更多的参数【JDK自带】
Spring中Bean对象的存储与读取,spring,java,后端
经常用的是name参数,如果Spring中 @Bean 注解存储的Bean对象制定了名称,那么此时可以通过name属性用于指定获取对应名称的bean

同一个类型注入多个Bean对象
Spring中Bean对象的存储与读取,spring,java,后端
获取Bean对象的时候需要指定bean名称,否则会在运行时报错
Spring中Bean对象的存储与读取,spring,java,后端
此时因为是user1,@Autowired现根据type查找会发现有多个User类型的Bean对象然后再根据name查找就会获取到user1的bean对象
此时对于开发而言,user1这样的明明肯定不符合规定,因此需要一个修改一下bean的名字才行。所以引入了@Resource注解
Spring中Bean对象的存储与读取,spring,java,后端
但是@Resource注解由于不支持构造方法注入,如果仍然想用Spring的@Autowired注解使用构造方法注入就需要引入一个新注解解决名字的问题:@Qualifier
Spring中Bean对象的存储与读取,spring,java,后端

@Autowired VS @Resource

@Autowired @Resouce
来源 来自Spring 来自 JDK
使用时参数不同 搭配@Qualifier获取指定名称bean 支持更多的参数,可以设置 name 来获取指定 Bean
修饰对象不同 修饰属性,构造方法,Setter 修饰属性,Setter

Bean的生命周期

对象注入
Spring中Bean对象的存储与读取,spring,java,后端
对象获取
Spring中Bean对象的存储与读取,spring,java,后端
运行结果
Spring中Bean对象的存储与读取,spring,java,后端

修改前: Dog{id=1, name='旺财', age=1}
修改后: Dog{id=1, name='喵喵', age=1}
后续获取: Dog{id=1, name='喵喵', age=1}

会发现由于单例模式,导致公共的Bean对象被修改之后,后续获取的Bean都会被修改
因此就引入Bean的作用域【从之前的代码区域提升到现在框架区域】

  1. singleton: 单例
    Spring默认作用域,通常无状态的Bean使用该作用域

    无状态:表示该Bean对象的属性状态不需要更新

  2. prototype: 原型【多例】
    通常有状态的Bean使用该作用域
  3. request: 请求
    每次http请求会创建新的Bean,同一次http请求中创建的bean是同一个Bean【限定Spring MVC中使用】
  4. session: 会话
    同一个http session中创建的Bean是同一个Bean【限定Spring MVC中使用】
  5. application: 全局
    在同一个Spring上下文中创建的Bean是同一个Bean【限定Spring MVC中使用】
  6. websocket: HTTP WebSocket作用域
    在一个WebSocket的生命周期中创建的Bean是同一个Bean【限定Spring WebSocket中使用】

设置的方式有两种
Spring中Bean对象的存储与读取,spring,java,后端
此时运行结果

修改前: Dog{id=1, name='旺财', age=1}
修改后: Dog{id=1, name='喵喵', age=1}
后续获取: Dog{id=1, name='旺财', age=1}

Bean的生命周期

  1. 实例化【≠初始化,仅仅是分配内存空间】
  2. 设置属性【DI依赖注入】
  3. 初始化
    • 执行各种通知
    • 初始化的前置方法
      xml:义init-method
      注解:@PostConstruct注解
    • 初始化方法
    • 初始化后置方法
  4. 使用Bean
  5. 销毁Bean

会发现注解的执行顺序先于xml文章来源地址https://www.toymoban.com/news/detail-820164.html

Spring 主要执行流程

  1. 启动容器
    Spring中Bean对象的存储与读取,spring,java,后端
  2. Bean初始化
    配置文件中的扫描路径,扫描路径下的类
    Spring中Bean对象的存储与读取,spring,java,后端
  3. 注入Bean
    扫描路径下将带有5大类注解的类添加进Spring IoC容器中
  4. 使用Bean
    @Bean、@Autowired、@Resource注解将对应的方法、类成员进行装配
  5. 销毁Bean
  6. 关闭容器

到了这里,关于Spring中Bean对象的存储与读取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring(二):更简单的存储与读取 Bean

    通过上一章的Spring,我们基本实现了Spring 的读取与存储,但是在操作过程中,读取与存储并没有那么得“简单” 一套流程还是很复杂,所以,本章来介绍更加简单得读取与存储。 在 Spring 中想要更简单的存储和读取对象的核⼼是使⽤注解,也就是我们接下来要学习 Spring 中的

    2024年02月15日
    浏览(27)
  • Spring使用注解存储Bean对象

    在前一篇博客中( Spring项目创建与Bean的存储与读取(DL))介绍的是通过配置文件注册对象从而存储到 Spring 中,这种方式其实还是挺繁琐的。 实际上,在使用学习使用 Spring过程中,当我们要实现一个功能的时候,先应该考虑的是有没有相应的注解是实现对应功能的,Spring 中

    2024年02月16日
    浏览(34)
  • 使用Spring的五大类注解读取和存储Bean

    目录 1.存储Bean对象的注解 1.1 五大类注解 1.2 方法注解 1.3添加注解的依赖 2.注解的使用 2.1  controller注解 2. 2Service注解  2.3.Resopsitory注解 2.4Component注解 2.5Configuration注解 2.6 注解之间的关系 3.方法注解 3.1 方法注解要配合类注解来使用。 3.2 重命名Bean 4.获取Bean对象(对象装配

    2024年02月01日
    浏览(32)
  • spring中存储和获取bean对象

    存储 Bean 分为以下 2 步: 存储 Bean 之前,先得有 Bean 才⾏,因此先要创建⼀个 Bean, 说白了也就是写一个类。 告诉spring,把这个类的对象存起来。 编写 User 类, 有 sayHi 方法。 告诉 spring ,把这个类的对象存起来。 在配置文件中可以通过 bean 标签来告诉 spring 把对象存起来。

    2024年02月15日
    浏览(34)
  • Spring项目创建与Bean的存储与读取(DL)

    第一步,创建 Maven 项目 ,Spring 也是基于 Maven 的。 由于国外源不稳定,可能让下面第二步引入 Spring 依赖会失败,所以这里先介绍如何一下配置国内镜像源。 现成的 settings.xml 文件链接:gitee 如果你已经有了 settings.xml 文件,但没有配置 mirror ,配置内容如下: 如果你是在引

    2024年02月17日
    浏览(28)
  • Spring——更快捷的存储 / 获取Bean对象

    本人是一个普通程序猿!分享一点自己的见解,如果有错误的地方欢迎各位大佬莅临指导,如果你也对编程感兴趣的话,互关一下,以后互相学习,共同进步。这篇文章能够帮助到你的话,劳请大家点赞转发支持一下! 上篇文章中,向Spring容器中添加对象,还要去配置文件里手动添

    2024年02月15日
    浏览(33)
  • Spring使用注解存储和读取对象

    之前我们存储Bean时,需要在spring-config.xml中添加bean注册才行,这样的方式并不简单。我们要想 更简单的存储和读取对象的核心是使用注解 1.使用类注解(五大类注解): @Controller:控制器,验证用户请求的数据正确性(安保系统) @Service:服务层,编排和调度具体执行方法的(客服

    2023年04月19日
    浏览(34)
  • Spring 更简单的读取和存储对象

    在 Spring 中要想更简单的存储和读取对象 , 核心是 使用注解 , 所以我们需要通过 Spring 中相关注解 , 来存储和读取 Bean 对象. 之前我们存储 Bean 时 , 需要在 spring-config.xml 中添加一行注释才行: 而现在我们只需一个注解就可以替代之前要写一行配置 , 不过在存储对象之前 , 我们先

    2024年02月02日
    浏览(31)
  • 【Spring框架全系列】Spring更简单的读取和存储对象

    📬📬哈喽,大家好,我是小浪。上篇博客我们介绍了如何创建一个spring项目,并且如何的存、取对象,介绍了相关方法,那么本篇博客将接着上篇博客的内容介绍如何更加简单的读取和存储对象。 🌃在 Spring 中想要更简单的存储和读取对象的核⼼是使⽤注解,也就是我们接

    2024年02月05日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包