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

Spring - 14 ( 5000 字 Spring 入门级教程 )

一:Spring原理

1.1 Bean 作用域的引入

在 Spring 的 IoC 和 DI 阶段,我们学习了 Spring 如何有效地管理对象。主要内容包括:

  1. 使用 @Controller、@Service、@Repository、@Component、@Configuration 和 @Bean 注解来声明 Bean 对象。
  2. 通过 ApplicationContext 或 BeanFactory 获取对象实例。
  3. 通过 @Autowired、Setter 方法或构造方法等方式将所依赖的 Bean 对象注入到应用程序中。

Bean 的作用域指的是 Bean 在 Spring 框架中的特定行为模式。例如,单例作用域表示同一个 Bean 在整个 Spring 容器中只有一个实例,是全局共享的。如果一个 Bean 的值被某个组件修改,则其他组件读取到的将是被修改后的值,这是 Spring 默认采用的行为模式。

1.2 Bean 作用域

在 Spring 中,共支持六种作用域,其中后四种作用域仅在 Spring MVC 环境中有效:

  1. singleton:单例作用域,表示整个 Spring 容器中同名称的 Bean 只有一个。
  2. prototype:原型作用域又叫做多例作用域,表示每次使用该 Bean 的时候都会创建一个新的。
  3. request:请求作用域,表示在一次 HTTP 请求中创建一个 Bean 实例,该实例在请求结束后销毁。
  4. session:会话作用域,表示在一个 HTTP 会话中只存在一个 Bean 实例,直到会话结束。
  5. application:全局作用域,表示在整个应用上下文中只有一个 Bean 实例。
  6. websocket:HTTP WebSocket 作用域,表示在 WebSocket 会话中只存在一个 Bean 实例。

下面一起来看看代码吧:

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
import org.springframework.web.context.annotation.SessionScope;
import org.springframework.web.context.annotation.ApplicationScope;

@Component
public class DogBeanConfig {

    @Bean
    public Dog dog() {
        Dog dog = new Dog();
        dog.setName("旺旺");
        return dog;
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    public Dog singleDog() {
        return new Dog();
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Dog prototypeDog() {
        return new Dog();
    }

    @Bean
    @RequestScope
    public Dog requestDog() {
        return new Dog();
    }

    @Bean
    @SessionScope
    public Dog sessionDog() {
        return new Dog();
    }

    @Bean
    @ApplicationScope
    public Dog applicationDog() {
        return new Dog();
    }
}

下面测试不同作用域的 Bean 取到的对象是否⼀样:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DogController {

    @Autowired
    private Dog singleDog;

    @Autowired
    private Dog prototypeDog;

    @Autowired
    private Dog requestDog;

    @Autowired
    private Dog sessionDog;

    @Autowired
    private Dog applicationDog;

    @Autowired
    private ApplicationContext applicationContext;

    @RequestMapping("/single")
    public String single() {
        Dog contextDog = (Dog) applicationContext.getBean("singleDog");
        return "dog: " + singleDog.toString() + ", contextDog: " + contextDog.toString();
    }

    @RequestMapping("/prototype")
    public String prototype() {
        Dog contextDog = (Dog) applicationContext.getBean("prototypeDog");
        return "dog: " + prototypeDog.toString() + ", contextDog: " + contextDog.toString();
    }

    @RequestMapping("/request")
    public String request() {
        Dog contextDog = (Dog) applicationContext.getBean("requestDog");
        return "dog: " + requestDog.toString() + ", contextDog: " + contextDog.toString();
    }

    @RequestMapping("/session")
    public String session() {
        Dog contextDog = (Dog) applicationContext.getBean("sessionDog");
        return "dog: " + sessionDog.toString() + ", contextDog: " + contextDog.toString();
    }

    @RequestMapping("/application")
    public String application() {
        Dog contextDog = (Dog) applicationContext.getBean("applicationDog");
        return "dog: " + applicationDog.toString() + ", contextDog: " + contextDog.toString();
    }
}

下面观察一下 Bean 的作用域:

  1. 单例作用域:http://127.0.0.1:8080/single

在这里插入图片描述
多次访问后获得的都是同一个对象,同时使用 @Autowired 注入的对象和通过 applicationContext.getBean() 获取的对象也是相同的实例。

  1. 多例作用域:http://127.0.0.1:8080/prototype

在这里插入图片描述

观察 contextDog,每次获取的对象都是不同的。因为注入的对象在 Spring 容器启动时就已经注入,因此在多次请求中,注入的对象不会发生变化。

  1. 请求作用域:http://127.0.0.1:8080/request

在这里插入图片描述
在一次请求中,@Autowired 注入的对象和通过 applicationContext.getBean() 获取的对象是同一个实例。然而,在每次请求中,applicationContext.getBean() 会重新创建新对象。

  1. 会话作用域:http://127.0.0.1:8080/session

在这里插入图片描述

在这里插入图片描述

在同一个会话中,经过多次请求后获取到的对象都是相同的。然而,当换用另一个浏览器访问时,会重新创建一个新的对象,因为这将启动一个不同的会话。

  1. Application 作用域:http://127.0.0.1:8080/application

在这里插入图片描述

在一个应用中,多次访问返回的都是同一个对象。Application scope 表示 Bean 的作用域是 ServletContext 级别,这与 singleton 类似,但二者之间有一定区别:Application scope 是 ServletContext 的单例,而 singleton 是 ApplicationContext 的单例。在一个 Web 容器中,可以存在多个 ApplicationContext。

1.2 Bean 的生命周期

生命周期指的是一个对象从创建到销毁的整个过程,通常称为对象的生命周期。Bean 的生命周期可以分为以下五个部分:

  1. 实例化:为 Bean 分配内存空间。
  2. 属性赋值:进行 Bean 注入和装配,例如 @Autowired。
  3. 初始化:执行各种通知和初始化方法。
  4. 使用 Bean:在应用中使用已配置的 Bean。
  5. 销毁 Bean:通过容器的各种销毁方法。

在这里插入图片描述

import com.example.demo.component.UserComponent;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class BeanLifeComponent implements BeanNameAware {
    
    private UserComponent userComponent;

    public BeanLifeComponent() {
        System.out.println("执行构造函数");
    }

    @Autowired
    public void setUserComponent(UserComponent userComponent) {
        System.out.println("设置属性 userComponent");
        this.userComponent = userComponent;
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("执行了 setBeanName 方法:" + s);
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("执行 PostConstruct()");
    }

    public void use() {
        System.out.println("执行了 use 方法");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("执行:preDestroy()");
    }
}

在这里插入图片描述

1.3 源码阅读

这里等作者好好研究一下,研究好了再来补充。。。。

二:Spring Boot 自动配置

Spring Boot 的自动配置是在 Spring 容器启动后,自动将一些配置类和 Bean 对象存入 IoC 容器,无需手动声明,从而简化了开发,减少了繁琐的配置操作。自动配置的核心在于 Spring Boot 如何将依赖的 Jar 包中的配置类和 Bean 加载到 Spring IoC 容器中。我们学习的内容主要分为以下两个方面:

  1. Spring 是如何把对象加载到 Spring IoC 容器中的
  2. SpringBoot 是如何实现的

2.1 占位

占个位,等作者研究好了过来补充一下。。。。。。

相关文章:

  • Linux网络http与https
  • LeetCode面试热题150中6-11题学习笔记(用Java语言描述)
  • 通过 spring ai 对接 deepseek ai 大模型通过向量数据库,完成 AI 写标书及构建知识库功能的设计与开发
  • 简约美观的地址发布页PHP源码带后台
  • 【3】k8s集群管理系列--包应用管理器helm之chart资源打包并推送到harbor镜像仓库
  • 粉末冶金齿轮学习笔记分享
  • Honor of Kings (S39) 13-win streak
  • Python中NumPy的随机操作
  • 5.1 GitHub订阅监控系统实战:FastAPI+SQLAlchemy高效架构设计与核心源码揭秘
  • 从一到无穷大 #45:InfluxDB MCP Server 构建:从工程实践到价值重构
  • 探秘 Python 网络编程:构建简单聊天服务器
  • RFID技术概览
  • 深入理解linux操作系统---第3讲 基本操作与基本管理
  • GD32的中断、定时器与PWM综合使用
  • FEA 仿真助力高速连接器设计中的信号完整性
  • 碰一碰发视频源码搭建技术开发,私有化部署,定制化开发
  • 【OpenCV】【XTerminal】talk程序运用和linux进程之间通信程序编写,opencv图像库编程联系
  • 数智读书笔记系列028 《奇点更近》
  • 批量给文件夹编排序号,支持数字序号及时间日期序号编排文件夹
  • 数组对象[object],五种如何去重方法 js