Java Spring

news2025/1/19 23:13:59

文章目录

  • Spring
    • Spring 是什么?
    • 从Spring中获取Bean
        • xml获取
        • 注解存储
          • 类注解
          • ⽅法注解
          • bean命名规则
          • 类注解之间的关系
        • 注解获取bean
          • 属性注⼊
            • 缺点
          • 构造⽅法注⼊
          • Setter 注⼊
          • 三种注⼊优缺点分析
          • @Resource:另⼀种注⼊关键字
          • 同⼀类型多个 Bean 报错处理
      • 获取bean对象的几种方式
      • ApplicationContext VS BeanFactory
    • Bean 作⽤域
      • singleton
      • prototype
      • request
      • session
      • application(了解)
      • websocket(了解)
      • 单例作⽤域(singleton) VS 全局作⽤域(application)
      • 设置作⽤域
    • Spring 执⾏流程
    • Bean的生命周期

Spring

Spring 是什么?

  • 一个包含了众多工具方法的 IOC容器

  • IOC

    • 控制反转
      • 控制权的反转
      • 控制对象的生命周期
  • DI 是 Dependency Injection 的缩写,翻译成中⽂是“依赖注⼊”的意思

    • 所谓依赖注⼊,就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中

从Spring中获取Bean

xml获取
  1. spring-config.xml配置

    • 建立 beanid 与 类名的 映射

    • <?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"></content:component-scan>-->
      
          <!--    <bean id="myComponent" class="com.demo.component.BeanLifeComponent"-->
          <!--          init-method="init"></bean>-->
              <bean id="user" class="org.example.User"/>
      </beans>
      
  2. 先获取Spring上下文

    • image-20231119212741663
  3. 从spring中取出Bean对象

    • User user = (User) context.getBean("user"); //通过 id
      User user1 = context.getBean(User.class); // 通过类名.class
      User user2 = context.getBean("user", User.class); // 不需要强转了
      System.out.println(user1.Hi());
      
  • 操作流程如下图所示:
    • image-20231119223022215
注解存储
  • jdk1.5之后才有注解

  • 扫描指定包下的类注册到 spring中

    • <content:component-scan base-package="org.example"></content:component-scan>
      
类注解
  • @Controller

    • 控制器
      • 业务逻辑层
  • @Service

    • 服务层
      • 调用持久化实现相应的功能
  • @Repository

    • 持久层
      • 直接与数据库做交互
      • 通常每一个表都会对应一个 @Repository
  • @Component

    • 组件
      • 归属于公共工具类,提供一些公共方法
  • @Configuration

    • 配置层
      • 用来配置当前项目的一些信息
  • image-20231120131858547

⽅法注解
  • @Bean

    • 将当前修饰方法的返回类 存储到 spring中
  • 使用:

    • ⽅法注解 @Bean 一定要配合类注解才能将对象正常的存储到 Spring 容器中

      • @Component
        public class StudentBeans {
        
            @Bean
            public Student student(){
                Student student = new Student();
                student.setId(1);
                return student;
            }
        }
        
    • 默认情况下,Bean name 等于 方法名

      • 可以重命名 Bean

        • @Component
          public class StudentBeans {
          
              @Bean(name = {"s1","s2"})
              public Student student(){
                  Student student = new Student();
                  student.setId(1);
                  return student;
              }
          }
          
  • BeanFactory不能支持@Bean

bean命名规则
  • spring通过调用jdk的工具方法类还生成注解的名字的
    • 判断第一和第二个 都是大写
      • 则直接返回name
    • 假如第二个不是
      • 则将首字母小写,返回
    • image-20231120125050779
类注解之间的关系
  • 查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发现
    • 其实这些注解⾥⾯都有⼀个注解 @Component,说明它们本身就是属于 @Component 的“⼦类”
    • image-20231120132843763
注解获取bean
属性注⼊
  • @Data
    public class Student {
        private int id;
    
        @Autowired
        private User user;
    
    }
    
缺点
  • 功能性问题:
    • 不能注入 不可变/final对象
      • 因为 jdk 规定 了 final 必须要在 初始化 和 构造函数中 赋值
  • 通用性问题:
    • 只适用于 IOC容器
  • 设计原则问题:
    • 更加容易违背单一设计原则
构造⽅法注⼊
  • @Component
    public class Student {
        private int id;
    
        private  User user;
        @Autowired
        public Student(User user){
            this.user = user;
        }
    }
    
  • 注意事项

    • 如果只有⼀个构造⽅法,那么 @Autowired 注解可以省略,如下图所示:

      • @Component
        public class Student {
            private int id;
        
            private  User user;
            public Student(User user){
                this.user = user;
            }
        }
        
      • 但是如果类中有多个构造⽅法,那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法

  • 优点:

    • 可以注入不可变对象
    • 注入对象不会被修改
      • 可以加final
      • 构造函数只会在类加载的时候执行一次
Setter 注⼊
  • Setter 注⼊和属性的 Setter ⽅法实现类似

    • 只不过在设置 set ⽅法的时候需要加上 @Autowired 注解,如下代码所示:

      • @Component
        public class Student {
            private int id;
        
            private  User user;
        
            @Autowired
            public void setUser(User user) {
                this.user = user;
            }
        }
        
  • 缺点:

    • 不可注入不可变对象

    • 注入对象可被修改

      • @Autowired
        public void setUser(User user) {
            this.user = user;
            this.user = null;
        }
        
三种注⼊优缺点分析
  • 属性注⼊的优点是简洁,使⽤⽅便;
    • 缺点是只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常)
  • 构造⽅法注⼊是 Spring 推荐的注⼊⽅式
    • 它的缺点是如果有多个注⼊会显得⽐较臃肿,但出现这种情况你应该考虑⼀下当前类是否符合程序的单⼀职责的设计模式了
    • 它的优点是通⽤性,在使⽤之前⼀定能把保证注⼊的类不为空
  • Setter ⽅式是 Spring 前期版本推荐的注⼊⽅式,但通⽤性不如构造⽅法
    • 所有 Spring 现版本已经推荐使⽤构造⽅法注⼊的⽅式来进⾏类注⼊了
@Resource:另⼀种注⼊关键字
  • 可以使⽤ @Autowired 关键字之外,我们还可以使⽤ @Resource 进⾏注⼊,如下代码所示

    • @Component
      public class Student {
          private int id;
      
          @Resource
          private  User user;
      
      }
      
  • @Autowired 和 @Resource 的区别

    • 相同点:
      • 都是用来实现依赖注入的注释
    • 不同:
      • 出身不同:
        • @Autowired 来⾃于 Spring,⽽ @Resource 来⾃于 JDK 的注解;
      • 使⽤时设置的参数不同:
        • 相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如name 设置,根据名称获取 Bean。
      • @Autowired 可⽤于 Setter 注⼊、构造函数注⼊和属性注⼊
      • ⽽ @Resource 只能⽤于 Setter 注⼊和属性注⼊,不能⽤于构造函数注⼊
同⼀类型多个 Bean 报错处理
  • 解决同⼀个类型,多个 bean 的解决⽅案有以下两个:

    • 使⽤ @Resource(name=“user1”) 定义。

      • @Component
        public class Student {
            private int id;
        
            @Resource(name = "user1")
            private  User user;
        
        }
        
    • 使⽤ @Qualifier 注解定义名称。

      • @Component
        public class Student {
            private int id;
        
            @Autowired
            @Qualifier(value = "user1")
            private  User user;
        
        }
        

获取bean对象的几种方式

  1. 根据名称获取Bean

  2. 根据Bean类型来获取Bean

  3. 根据Bean名称 + Bean类型来获取Bean

    • User user = (User) context.getBean("user"); //通过 id
      User user1 = context.getBean(User.class); // 通过类名.class
      User user2 = context.getBean("user", User.class); // 不需要强转了
      

ApplicationContext VS BeanFactory

  • 继承关系和功能⽅⾯来说:Spring容器有两个顶级的接⼝:
    • BeanFactory和ApplicationContext。其中BeanFactory提供了基础的访问容器的能⼒
    • ApplicationContext属于BeanFactory的⼦类,它除了继承了BeanFactory的所有功能之外
      • 它还拥有独特的特性,还添加了对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持
  • 从性能⽅⾯来说:
    • ApplicationContext是⼀次性加载并初始化所有的Bean对象,⽽BeanFactory是需要那个才去加载那个,因此更加轻量。

Bean 作⽤域

  • Spring 容器在初始化⼀个 Bean 的实例时,同时会指定该实例的作⽤域。
  • Spring有 6 种作⽤域,最后四种是基于 Spring MVC ⽣效的:
    1. singleton:单例作⽤域
    2. prototype:原型作⽤域(多例作⽤域)
    3. request:请求作⽤域
    4. session:回话作⽤域
    5. application:全局作⽤域
    6. websocket:
      • HTTP WebSocket 作⽤

注意后 4 种状态是 Spring MVC 中的值,在普通的 Spring 项⽬中只有前两种

singleton

  • 描述:

    • 该作⽤域下的Bean在IoC容器中只存在⼀个实例
      • 获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对象。
  • 场景:

    • 通常⽆状态的Bean使⽤该作⽤域。
    • ⽆状态表示Bean对象的属性状态不需要更新
  • 备注:

    • Spring默认选择该作⽤域

prototype

  • 描述:

    • 每次对该作⽤域下的Bean的请求都会创建新的实例
      • 获取Bean(即通过applicationContext.getBean等⽅法获取)
      • 及装配Bean(即通过@Autowired注⼊)都是新的对象实例
  • 场景:通常有状态的Bean使⽤该作⽤域

request

  • 描述:

    • 每次http请求会创建新的Bean实例,类似于prototype
  • 场景:

    • ⼀次http的请求和响应的共享Bean
  • 备注:限定SpringMVC中使⽤

session

  • 描述:在⼀个http session中,定义⼀个Bean实例
  • 场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息
  • 备注:限定SpringMVC中使⽤

application(了解)

  • 描述:在⼀个http servlet Context中,定义⼀个Bean实例
    • 一个上下文对象共享
  • 场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息
  • 备注:限定SpringMVC中使⽤

websocket(了解)

  • 描述:在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例
  • 场景:
    • WebSocket的每次会话中
      • 保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。
    • 第⼀次初始化后,直到WebSocket结束都是同⼀个Bean

单例作⽤域(singleton) VS 全局作⽤域(application)

  • singleton 是 Spring Core 的作⽤域
    • application 是 Spring Web 中的作⽤域
  • singleton 作⽤于 IoC 的容器
    • ⽽ application 作⽤于 Servlet 容器

设置作⽤域

  • 使⽤ @Scope 标签就可以⽤来声明 Bean 的作⽤域

    • ⽐如设置 Bean 的作⽤域,如下代码所示:

      • @Component
        @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
        public class User {
            public String Hi(){
                return "哈你妈个头";
            }
        }
        
  • @Scope 标签既可以修饰⽅法也可以修饰类,@Scope 有两种设置⽅式:

    • 直接设置值:@Scope(“prototype”)
    • 使⽤枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Spring 执⾏流程

  • Bean 执⾏流程(Spring 执⾏流程):

    1. 启动容器(项目)
    2. 读取配置文件
      1. 使用xml直接注册bean
      2. 配置bean根(扫描)路径
    3. 将bean存储到 spring中
      • 通过类注解进行扫描和装配
    4. 将bean从spring中读出,配置相应的类
    • image-20231121131401010

Bean的生命周期

  • 所谓的⽣命周期指的是⼀个对象从诞⽣到销毁的整个⽣命过程,我们把这个过程就叫做⼀个对象的⽣命周期。

  • Bean 的⽣命周期分为以下 5 ⼤部分:

    1. 实例化 Bean(为 Bean 分配内存空间)

      • 将字节码转换为内存中的对象
      • 调用构造函数
    2. 设置属性(Bean 注⼊和装配)

      • 设置类的属性
    3. Bean 初始化

      • 实现了各种 Aware 通知的⽅法

        • 如 BeanNameAware、BeanFactoryAware、ApplicationContextAware 的接⼝⽅法;
      • 执⾏ BeanPostProcessor 初始化前置⽅法;

      • 执⾏ @PostConstruct 初始化⽅法,依赖注⼊操作之后被执⾏;

        • @PostConstruct
             public void init() {
                 // Initialization logic
                 System.out.println("Bean is being initialized...");
             }
          
      • 执⾏⾃⼰指定的 init-method ⽅法(如果有指定的话);

        • <bean id="myBean" class="com.example.MyBean" init-method="init">
              <!-- Other bean configurations -->
          </bean>
          
      • 执⾏ BeanPostProcessor 初始化后置⽅法

      • image-20231121134121960

    4. 使⽤ Bean

    5. 销毁 Bean

      • 销毁容器的各种⽅法,如 @PreDestroy、DisposableBean 接⼝⽅法、destroy-method
  • 执⾏流程如下图所示

    • image-20231121131758758

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

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

相关文章

谈一谈什么是接口测试?怎样做接口测试?

扫盲内容&#xff1a; 1.什么是接口&#xff1f; 2.接口都有哪些类型&#xff1f; 3.接口的本质是什么&#xff1f; 4.什么是接口测试&#xff1f; 5.问什么要做接口测试&#xff1f; 6.怎样做接口测试&#xff1f; 7.接口测测试点是什么&#xff1f; 8.接口测试都要掌…

​极氪,中国传统汽车品牌电动化的样板间

这篇文章早就想写了&#xff0c;因为太忙的原因就一直跳票&#xff0c;正好最近两件事的出现&#xff0c;又触发了想写这篇文章的冲动。 两件事主要是&#xff1a; 一&#xff0c;10 月份各家陆续公布了单月销量以及累计销量&#xff1b; 二&#xff0c;极氪在北京正式发布了 …

CTF靶场搭建及Web赛题制作与终端docker环境部署

♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ ♡ ♥ 写在前面 ╔═══════════════════════════════════════════════════…

OSG文字-渐变文字(4)

渐变文字(osgText::FadeText类)继承自osgText::Text类继承关系图如图9-6所示 图9-6 osgText::FadeText的继承关系图 从继承关系图中可以看出&#xff0c;它继承自osgText::Text类&#xff0c;因此&#xff0c;它具备一般文字属性的设置方法这里不再重复说明。创建渐变文字与一般…

Python通过selenium调用IE11浏览器报错解决方法

前提 正常安装Python 工具&#xff0c;selenium 包可以正常导入。IE浏览器驱动 IEDriverServer.exe 已经正确放置到已经添加path目录的文件下。 报错现象&#xff1a; 解决方法 打开浏览器进入 internet 选项 切换到安全页签 &#xff0c;去除“应用保护模式” 再次调用验证…

进程API

linux下进程的api forkwaitexec fork #include <stdio.h> #include <stdlib.h> #include <unistd.h>/* linux环境运行 子进程并不是完全拷贝了父进程。具体来说&#xff0c;虽然它拥有自己的 地址空间&#xff08;即拥有自己的私有内存&#xff09;、寄存器…

2018-2022年富时罗素 ESG评分数据

2018-2022年富时罗素 ESG评分数据 1、时间&#xff1a;2018-2022年 2、指标&#xff1a;证券代码、证券简称、富时罗素ESG评分、 3、说明&#xff1a; 富时罗素ESG评级体系评估了中国大陆、香港、欧洲以及美国等市场上1800家中国上市企业股票&#xff0c;评估了7200多种证券…

LangChain库简介

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【10套模拟】【8、9】

关键字&#xff1a; 建立有序单链表、多维数组是特殊线性结构、直接选择排序、哈夫曼树高度及wpl、中序最后叶子先序最后也是、堆是完全二叉树、分块查找 统计二叉树结点数、统计二叉树值和、奇偶数划分、判断链表是否递增

docker报错standard init linux.go:228 exec user process caused: exec format error

1、报错 使用Dockerfile自己做的服务镜像&#xff0c;docker run时启动失败&#xff0c;报错如下&#xff1a; standard init linux.go:228 exec user process caused: exec format error2、原因一 当前服务器的CPU架构和构建镜像时的CPU架构不兼容。比如做镜像是在arm机器下…

2020年计网408

第33题 下图描述的协议要素是&#xff08; &#xff09;。I. 语法 II. 语义 III. 时序 A. 仅 I B. 仅 II C. 仅 III D. I、II 和 III 本题考察网络协议三要素的相关知识。 网络协议的三要素分别是语法、语义、同步&#xff08;时序&#xff09;。语法&#xff1a;定义收发双…

IPFoxy:什么是数据中心代理IP?好用吗?

数据中心代理是代理IP中最常见的类型&#xff0c;也被称为机房IP。这些代理服务器为用户分配不属于 ISP&#xff08;互联网服务提供商&#xff09;而来自第三方云服务提供商的 IP 地址。数据中心代理的最大优势——它们允许在访问网络时完全匿名。 如果你正在寻找海外代理IP&am…

力扣:175. 组合两个表(Python3)

题目&#xff1a; 表: Person ---------------------- | 列名 | 类型 | ---------------------- | PersonId | int | | FirstName | varchar | | LastName | varchar | ---------------------- personId 是该表的主键&#xff08;具有唯一值的列&#…

Raspberry Pi 5 新一代单板计算机:树莓派5代 (介绍、入门、解疑)

树莓派5代正式发布后&#xff0c;硬件和性能的全面升级让众多开发者们都想入手感受一波&#xff0c;外观上Raspberry Pi 5 与前代产品非常相似&#xff0c;不过&#xff0c;在保留信用卡大小的整体尺寸的同时&#xff0c;也更新了一些设计元素&#xff0c;以适应新芯片组的功能…

【c++】——类和对象(下) 万字解答疑惑

作者:chlorine 专栏:c专栏 目录 &#x1f6a9;再谈构造函数 &#x1f393;构造函数体赋值 &#x1f393;初始化列表 &#x1f6a9;explicit关键字 &#x1f6a9;static成员 &#x1f393;概念 面试题&#xff1a;计算创建多少个类对象 &#x1f393;特性 【问题】(非)…

机器学习实战第1天:鸢尾花分类任务

专栏介绍 欢迎订阅专栏——机器学习实战 机器学习实战_Nowl的博客-CSDN博客 纸上得来终觉浅 本专栏项目将着重于解决各类实际机器学习问题&#xff0c;带你上手各种场景的实际问题 数据集可以在我的资源中找到&#xff0c;也可以自行搜索 文中导入数据集的路径要改成自己的…

大图书馆 #9 《流计算系统图解》书评

上周&#xff0c;我收到清华大学出版社编辑寄来的新书《流计算系统图解》。趁着周末的功夫&#xff0c;我快速浏览了本书的主要内容。一句话评价&#xff1a;值得一读&#xff0c;尤其是对开始开发流计算任务或系统一到两年&#xff0c;初步实现过一些功能或作业&#xff0c;但…

【LeetCode刷题】-- 29.两数相除

29.两数相除 思路&#xff1a; class Solution {public int divide(int dividend, int divisor) {//考察被除数为最小值的情况if(dividend Integer.MIN_VALUE){//被除数为最小值&#xff0c;除数是1&#xff0c;返回最小值if(divisor 1){return Integer.MIN_VALUE;}//除数是-…

Java注解(Annotation)的基本知识

Java注解(Annotation)的基本知识 此文的目的只在于了解的注解的基本知识&#xff0c;知道注解的一些概念&#xff0c;使能够看懂注解的使用。 注解概述 Java 注解&#xff08;Annotation&#xff09;又称 Java 标注&#xff0c;使 JDK5.0 引入的一种注释机制。Java 语言中的…

ChatGPT 也并非万能,品牌如何搭上 AIGC「快班车」

内容即产品的时代&#xff0c;所见即所得&#xff0c;所得甚至超越所见。 无论是在公域的电商平台、社交媒体&#xff0c;还是品牌私域的官网、社群、小程序&#xff0c;品牌如果想与用户发生连接&#xff0c;内容永远是最前置的第一要素。 01 当内容被消费过&#xff0c;就…