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.mzph.cn/news/159538.shtml

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

相关文章

【React-Router】嵌套路由

1. 嵌套路由 在一级路由中又内嵌了其他路由&#xff0c;这种关系就叫做嵌套路由。 2. 嵌套路由配置 // /page/About/index.js const About () > {return (<div>二级路由 About 组件</div>) }export default About// /page/Layout/index.js import { Outlet, …

走进长光,看卫星是怎样炼成的?

在双11专场直播中&#xff0c;长光卫星嘉宾与大家分享了长光的科普教育基地。 这让我回想起了&#xff0c;我们去年到长光参观学习的场景。 让我们再次走进长光&#xff0c;在参观学习增长见识的同时&#xff0c;也可以看看卫星是怎样炼成的&#xff1f; 出发 2022年8月23日…

从零开始安装并运行YOLOv5

从零开始安装并运行YOLOv5 该文主要实现用YOLOv5的基准检测为自己的视频片段渲染对象检测结果和边界框&#xff0c;本文大部分都是实操&#xff0c;帮助大家快速上手。 什么是YOLOv5&#xff1f; ​ yolo是一种用于对象检测的最先进的机器学习模型&#xff0c;yolo有不同的版…

YOLOv5 分类模型 OpenCV和PyTorch两者实现预处理的差异

YOLOv5 分类模型 OpenCV和PyTorch两者实现预处理的差异 flyfish PyTorch封装了PIL库 简单对比下两者的使用方法 import cv2 from PIL import Image import numpy as npfull_path_file_name"/media/a//ILSVRC2012_val_00001244.JPEG"#OpenCV读取图像默认是BGR顺序 …

HTML5+CSS3+JS小实例:霁青+翠蓝的Tabbar动画特效

实例:霁青+翠蓝的Tabbar动画特效 技术栈:HTML+CSS+JS 字体图标库:Font Awesome 效果: 源码: 【HTML】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta nam…

提升效率必备:电脑文件批量重命名的实用技巧大放送

在日常工作中&#xff0c;电脑文件的重命名是一项常见的操作。当要处理大量的文件&#xff0c;并且要按照一定的规则或逻辑进行重命名时&#xff0c;手动一个一个重命名显然是非常低效的。掌握批量重命名的技巧可提高工作效率。现在一起来看云炫文件管理器如何批量重命名电脑上…

CmakeLists编译的动态库.so移动到其他位置后,提示找不到该库的依赖库解决办法

主要问题&#xff1a; 最近在搞海康SDK调用相机&#xff0c;发现在linux下一直调用不起来相机&#xff0c;总是提示error code&#xff1a;29&#xff0c;注册失败&#xff0c;重新编译优惠存在找不到依赖库的问题。 1.异常 CmakeLists编译的动态库.so移动到其他位置后&#…

Python Pandas简介及基础教程+实战示例。

文章目录 前言一、Pandas简介二、Python Pandas的使用关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 前言 Pan…

webpack项目 index.html 根据不同的变量引入不同的js

项目 webpack搭建 问题&#xff1a;在入口文件index.html中根据不同的变量引入不同的js 使用插件HtmlWebpackPlugin HtmlWebpackPlugin 项目里用来生成静态文件的 这个插件每个项目基本都要用到的&#xff0c;只要全局搜一下位置 根据配置文件的指令找到执行的文件&#xff0…

海外应用速度访问慢?试试这个技术解决方案

在数字化转型的时代&#xff0c;企业需要高效、稳定、安全的网络连接来支撑全球化业务的拓展。然而&#xff0c;在进行海外应用访问时&#xff0c;经常会遇到访问速度慢的问题&#xff0c;因为跨国界的网络通信往往存在延迟和带宽限制等问题。在过去&#xff0c;企业通常会使用…

Doris动态分区(十四)

动态分区是在 Doris 0.12 版本中引入的新功能。旨在对表级别的分区实现生命周期管理&#xff08;TTL&#xff09;&#xff0c;减少用户的使用负担。 目前实现了动态添加分区及动态删除分区的功能。动态分区只支持 Range 分区。 原理 在某些使用场景下&#xff0c;用户会将表…

计算机基础知识——字,字节,进制,short,byte等

目录 进制位&#xff0c;字节&#xff0c;字Byte&#xff0c;ShortByteBuf有符号数和无符号数 进制 HEX&#xff0c;Hexadecimal &#xff0c;十六进制。 DEC&#xff0c;Decimal &#xff0c;十进制。 OCT&#xff0c;Octal &#xff0c;八进制。 BIN&#xff0c;Binary &a…

【Android】声浪 UI 效果并附上详细代码

声浪效果是基于第三方实现的。 https://github.com/xfans/VoiceWaveView 将三方的 Kotlin 代码转 java 使用&#xff08;按照他的readme 进行依赖&#xff0c;好像少了点东西&#xff0c;至少本项目跑不起来&#xff09; 声浪效果在android 8 以上都是比较好的&#xff0c;不会…

外卖配送小程序商城的效果如何

线下餐饮店非常多&#xff0c;主要以同城生意为主&#xff0c;在线上电商和外卖平台的冲击下&#xff0c;传统商家仅通过传统方式经营很难宣传拓客及转化等&#xff0c;线上是必要的渠道&#xff0c;但入驻第三方平台又会有各种困扰&#xff0c;抽成/佣金/流量费/激烈竞争等。 …

【云原生-Kurbernetes篇】 玩转K8S不得不会的HELM

Helm 一、Helm1.1 使用背景1.2 Helm简介1.3 Helm的几个概念1.4 helm2 和 helm3 的区别1.5 chart包的关键组成 二、Helm相关命令2.1 应用管理操作2.2 Helm repository仓库管理命令2.2 Helm chart包管理命令2.3 Helm release(实例) 管理命令2.4 Helm私有仓库管理命令 三、部署He…

Linux常用操作 Vim一般使用 SSH介绍 SSH密钥登录

目录 1. 常用命令 2. vim一般使用 3. SSH介绍 4. ssh密钥登录 1. 常用命令 1&#xff09;# 与 $ 提示的区别 # 表示用户有root权限&#xff0c;一般的以root用户登录提示符为#&#xff0c; $提示符表示用户为普通用户 2&#xff09;ifconfig 查看ip地址 eno1: 代表由主板…

“图纸保密大作战:上海迅软DSE解决方案守护机械公司核心资料

机械行业是我国重要的工业制造行业之一&#xff0c;相关企业在发展中往往需要用到ERP、PDM、PLM等系统来对产品信息进行管理&#xff0c;其中便涉及到大量文档和图纸等重要数据。然而随着业务的快速发展和数字化转型&#xff0c;机械行业也面临着如数据泄露、外来袭击攻击、内部…

以45°斜抛水平距离最远

已知&#xff1a;斜抛物体的初速度为 v 0 v_0 v0​&#xff08;与水平方向的夹角为 θ \theta θ&#xff09;&#xff0c;重力加速度为 g g g。 求&#xff1a;抛物轨迹方程&#xff1f; 垂直方向的速度为 v y v 0 sin ⁡ θ − g t v_yv_0 \sin \theta -gt vy​v0​sinθ−…

CNVD-2023-12632:泛微E-cology9 browserjsp SQL注入漏洞复现 [附POC]

文章目录 泛微E-cology9 browserjsp SQL注入漏洞(CNVD-2023-12632)漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 泛微E-cology9 browserjsp SQL注入漏洞(CNVD-2023-12632)漏洞复现 [附POC] 0x…

如何查找批量企业的联系方式?

​我们都知道&#xff0c;企业的联系方式在企业的年报中就能找到&#xff0c;但是年报上的电话真的是你要找的吗&#xff1f; 很多企业年报上留的是第三方代记账公司&#xff0c;或者是其他没用的号码&#xff0c;这对于做B端业务的企业来说是不够精准的。 市面上有很多做企业…