Java Spring

文章目录

  • 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 {@Beanpublic 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;@Autowiredprivate User user;}
    
缺点
  • 功能性问题:
    • 不能注入 不可变/final对象
      • 因为 jdk 规定 了 final 必须要在 初始化 和 构造函数中 赋值
  • 通用性问题:
    • 只适用于 IOC容器
  • 设计原则问题:
    • 更加容易违背单一设计原则
构造⽅法注⼊
  • @Component
    public class Student {private int id;private  User user;@Autowiredpublic 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;@Autowiredpublic 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;@Resourceprivate  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 初始化⽅法,依赖注⼊操作之后被执⾏;

        • @PostConstructpublic void init() {// Initialization logicSystem.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.hqwc.cn/news/208809.html

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

相关文章

PDF转Word,1行Python代码就够了,免费用

大家好&#xff0c;这里是程序员晚枫。 今年十一假期没出去旅游&#xff0c;在家里更新一套原创课程&#xff0c;&#x1f449;给小白的《50讲Python自动化办公》。 所有功能&#xff0c;都只需要1行代码&#xff0c;非常适合非程序员入门Python使用。 目前全网播放量直逼100…

封装一个基于ThreeJS渲染基础模型的类,非常简单,可拖动可缩放

工作需求要求threeJS渲染一个模型以供可视化大屏展示&#xff0c;抛出模型精度不谈&#xff0c;只说业务实现 1.Three.JS的引入 ThreeJS官网地址:Three.js – JavaScript 3D Library 查看文档 中文切换及安装创建步骤 如果是自己研究学习用的&#xff0c;在官网安装完后&…

VScode调试没有反应

点击调试按钮后没反应 有可能是vscode中安装的python插件版本问题 可以通过重新安装比较旧一点的python尝试解决此问题 步骤如下&#xff1a; 然后从中选择比当前版本更低的版本即可 安装完成后需重启vscode

汇编-pop出栈指令

32位汇编 执行动作分为两步&#xff1a; 第一步&#xff1a;读出数据 第二步&#xff1a;改变栈地址 如果操作数是16位&#xff0c; 则ESP加2&#xff1b; 如果操作数是32位&#xff0c; 则ESP加4 espesp2 或 espesp4 格式&#xff1a;

ios qt开发要点

目前关于ios qt的开发资料比较少&#xff0c;这里整理了几个比较重要的开发要点&#xff0c;基于MacOS14 Xcode15 Qt15.5 cmake iphone真机。 cmake报错&#xff0c;报错信息如下 CMake Error at /Users/user/Qt/5.15.5/ios/lib/cmake/Qt5Core/Qt5CoreConfig.cmake:91 (m…

opencv-直方图

直方图是一种对图像亮度分布的统计表示&#xff0c;它显示了图像中每个灰度级别的像素数量。在OpenCV中&#xff0c;你可以使用cv2.calcHist() 函数计算直方图。 以下是一个简单的示例&#xff0c;演示如何计算和绘制图像的直方图&#xff1a; import cv2 import numpy as np …

for 循环变量的声明方式

获取字符串中的第一个单词&#xff0c;for 循环中的 &value 声明比较特殊&#xff0c;结合图1编译器的提示&#xff0c;value 是一个 u8 类型。 fn get_first_world(s: &str) -> &str {let bytes s.as_bytes();for (i, &value) in bytes.iter().enumerate…

Arthas 监听 Docker 部署的java项目CPU占比高的信息

1、Linux上安装Arthas wget https://alibaba.github.io/arthas/arthas-boot.jar2、docker ps 查看目标项目的容器ID 3、copy Arthas 到目标容器中 (注意有 &#x1f615; ) docker cp arthas-boot.jar d97e8666666:/4、进入到目标容器目录中 docker exec -it d97e8666666 /b…

【VScode】安装配置、插件及远程SSH连接

一、VSCode安装 二、配置安装插件 三、配置远程连接SSH 四、MinGW 一、VSCode安装 VS官网 Visual Studio Code - Code Editing. Redefined下载安装包&#xff1a; 二、配置安装插件 安装中文插件 配置字体为20 配置文件–>首选项->设置->Font Size为20 设置 VSC…

git stash 用法总结

目录 1&#xff0c;介绍场景1&#xff1a;场景2&#xff1a; 2&#xff0c;常用命令2.1&#xff0c;基础2.2&#xff0c;进阶1&#xff0c;存储时指定备注2&#xff0c;通过索引来操作指定的存储3&#xff0c;修改存储规则 2.3&#xff0c;查看 stash 修改的具体内容 1&#xf…

洛谷 P4552 [Poetize6] IncDec Sequence

挺好的一道思维题。 分析 因为是对区间修改&#xff0c;多次修改肯定会超时&#xff0c;很容易想到差分。 那么原题的对区间修改就可以转换为下面三个操作&#xff08;均在差分数组中&#xff09;&#xff1a; 1. 任选一个数1 2. 任选一个数-1 3. 任选两个数1和-1 进一步考…

opencv-直方图均衡化

直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过调整图像的灰度级别分布&#xff0c;使得图像中各个灰度级别的像素分布更均匀&#xff0c;从而提高图像的对比度。 在OpenCV中&#xff0c;你可以使用cv2.equalizeHist()函数来进行直方图均衡化。 以下是一个简单…