【Spring】——Spring概述、IOC、IOC创建对象的方式、Spring配置、依赖注入(DI)以及自动装配知识

news2024/9/9 6:04:50

🎼个人主页:【Y小夜】

😎作者简介:一位双非学校的大二学生,编程爱好者,

专注于基础和实战分享,欢迎私信咨询!

🎆入门专栏:🎇【MySQL,Java基础,Rust】

🎈热门专栏:🎊【Python,Javaweb,Vue框架】

感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持!❤️

目录

🎯 Spring概述

😎Spring简介

😎优缺点

😎组成

🎯 IOC

😎本质

🎯IOC创建对象方式

😎无参构造

😎有参构造方法

🎯Spring配置

😎Bean的配置

🎯依赖注入(DI)

😎set注入 

✨Bean注入

✨ 数组注入

✨List注入

✨Map注入

✨set注入

😎Bean的作用域

✨Singleton模式

😎Prototype模式

🎯自动装配

😎重点

😎byName

😎byType

😎使用注解

✨Autowired

✨Qualifier

✨@Resource

😎小结


🎯 Spring概述

😎Spring简介

        Spring是一个轻量级、开源的Java EE应用程序框架,旨在解决企业级应用开发的复杂性,提供一种快速、可重用、易于测试的开发模式

        Spring由Rod Johnson在2002年发起,并在2004年正式发布了1.0版本。它通过其核心功能——控制反转(IoC)和面向切面编程(AOP),极大地简化了Java应用的开发过程。

        作为一个分层架构的全栈框架,Spring包含多个模块,从数据访问到业务层,再到表现层,几乎涵盖了开发过程中的所有方面。其中,Core Container是整个框架的基础,包括BeanFactory接口和上下文模块。BeanFactory使用控制反转模式,将对象的创建和管理交由Spring容器负责,从而降低了应用组件之间的耦合度。

        Spring的AOP模块则提供了强大的支持,允许开发者在不修改原有业务逻辑的情况下,添加或修改系统级别的服务,如事务管理和安全控制。这使得代码的可重用性和可测试性得到了显著提升。

😎优缺点

  • 优点
    1. 方便解耦:通过Spring提供的IoC(控制反转)容器,对象的依赖关系可以交由Spring进行控制,避免硬编码所造成的过度耦合。这样,开发者可以更专注于业务逻辑的设计和实现。
    2. 面向切面编程:Spring的AOP(面向切面编程)功能,使开发者能够以声明式方式进行事务管理、权限拦截和运行监控等功能,显著提高开发效率和质量。
    3. 声明式事务支持:Spring提供了强大的声明式事务管理支持,使得原本繁琐的事务管理代码变得简单且易于维护。
    4. 集成各种框架:Spring可以与Struts、Hibernate、MyBatis等多种优秀的开源框架无缝集成,降低这些框架的使用难度,提升整体开发效率。
    5. 降低API使用难度:Spring对JavaEE API(如JDBC、JavaMail等)进行了薄薄的封装层,使得这些API的使用难度大为降低。
  • 缺点
    1. 学习曲线陡峭:Spring框架功能强大且内容丰富,涉及众多概念和技术,初学者需要花费大量时间来掌握。
    2. 配置文件较多:Spring需要管理多个配置文件,如果设置不当,可能导致应用程序出现各种问题,排查和修复这些问题可能比较麻烦。
    3. 运行效率相对较低:由于Spring提供了丰富的功能和组件,其运行效率可能低于一些轻量级框架,但在现代计算机硬件的支持下,这种差异通常可以忽略不计。
    4. 代码量较大:使用Spring意味着需要编写和维护更多的代码,这可能会增加项目的复杂度和维护难度。
    5. 版本更新较快:Spring的版本更新频繁,新版本可能引入新功能同时废弃旧功能,这要求开发者不断适应和学习。

😎组成

        Spring 框架是一个分层架构,由 7 个定义良好的模块组成。 Spring 模块构建在核心容器之上,核心容器 定义了创建、配置和管理 bean 的方式 .

  1. 核心容器
    • spring-core模块:提供框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)功能。
    • spring-beans模块:提供BeanFactory,管理被称为“Bean”的对象。
    • spring-context模块:建立在Core和Beans模块之上,提供对象访问方式,并通过ApplicationContext接口进行访问。
    • spring-context-support模块:整合第三方库到Spring应用程序上下文,支持高速缓存和任务调度。
    • spring-expression模块:提供表达式语言以支持运行时查询和操作对象图。
  2. AOP和仪器支持
    • spring-aop模块:提供面向切面的编程实现,允许定义方法拦截器和切入点。
    • spring-aspects模块:与AspectJ集成,一个成熟的AOP框架。
    • spring-instrument模块:提供类植入支持和特定应用服务器中的类加载器实现。
  3. 数据访问与集成
    • spring-jdbc模块:提供JDBC抽象层,简化数据库操作。
    • spring-orm模块:集成Hibernate、JPA和JDO等ORM框架。
    • spring-oxm模块:提供Object-to-XML-Mapping的抽象层。
    • spring-jms模块:包含生产和使用消息的功能,自Spring4.1起,与spring-messaging模块集成。
    • spring-tx模块:事务模块,支持编程和声明式事务管理。
  4. Web
    • spring-websocket模块:实现双工异步通讯协议,提供Socket通信和推送功能。
    • spring-webmvc模块:包含Spring MVC和REST Web Services实现。
    • spring-web模块:提供基本Web开发集成功能,如文件上传支持和Filter类。
  5. 消息
    • spring-messaging模块:自Spring4.0新增,提供消息传递体系结构和协议支持。
  6. 测试
    • spring-test模块:支持使用JUnit或TestNG对Spring组件进行单元和集成测试。

🎯 IOC

😎本质

        控制反转IoC(Inversion of Control) ,是一种设计思想, DI( 依赖注入 ) 是实现 IoC 的一种方法 ,也有人认 为DI 只是 IoC 的另一种说法。没有 IoC 的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系 完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为 所谓控制反转就是:获得依赖对象的方式反转了。
        控制反转是一种通过描述(XML 或注解)并通过第三方去生产或获取特定对象的方式。在 Spring 中实现 控制反转的是 IoC 容器,其实现方法是依赖注入( Dependency Injection,DI )。

🎯IOC创建对象方式

😎无参构造

   实体类
public class User {
private String name;
public User() {
System.out.println("user无参构造方法");
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+ name );
}
}

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">
<bean id="user" class="com.aaa.pojo.User">
<property name="name" value="kkk"/>
</bean>
</beans>

测试类 

@Test
public void test(){
ApplicationContext context = new
ClassPathXmlApplicationContext("beans.xml");
//在执行getBean的时候, user已经创建好了 , 通过无参构造
User user = (User) context.getBean("user");
//调用对象的方法 .
user.show();
}

😎有参构造方法

public class UserT {
private String name;
public UserT(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+ name );
}
}

 beans.xml 有三种方式编写

<!-- 第一种根据index参数下标设置 -->
<bean id="userT" class="com.aaa.pojo.UserT">
<!-- index指构造方法 , 下标从0开始 -->
<constructor-arg index="0" value="aaa"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="userT" class="com.aaa.pojo.UserT">
<!-- name指参数名 -->
<constructor-arg name="name" value="aaa"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="userT" class="com.aaa.pojo.UserT">
<constructor-arg type="java.lang.String" value="aaa"/>
</bean>

🎯Spring配置

😎Bean的配置

<!--bean就是java对象,由Spring创建和管理-->
<!--
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name是别名
name可以设置多个别名,可以用逗号,分号,空格隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.aaa.pojo.Hello">
<prop

🎯依赖注入(DI

        依赖注入(DI)是一种通过将对象间的依赖关系转移给外部容器来管理的设计模式,以减少对象间的耦合性并提高代码的可重用性和可维护性

        在软件开发中,依赖注入主要解决的是对象之间复杂的依赖关系,以及如何将这些依赖关系管理得更加灵活和可扩展。通过将对象的创建和依赖关系的管理交给外部容器,依赖注入不仅降低了组件之间的耦合度,还提高了系统的可测试性和灵活性。

😎set注入 

常量注入

<bean id="student" class="com.aaa.pojo.Student">
<property name="name" value="小明"/>
</bean>

 测试

@Test
public void test01(){
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName());
}

Bean注入

注意点:这里的值是一个引用,ref

<bean id="addr" class="com.aaa.pojo.Address">
<property name="address" value="重庆"/>
</bean>
<bean id="student" class="com.aaa.pojo.Student">
<property name="name" value="小明"/>
<property name="address" ref="addr"/>
</bean>

✨ 数组注入

<bean id="student" class="com.aaa.pojo.Student">
<property name="name" value="小明"/>
<property name="address" ref="addr"/>
<property name="books">
<array>
<value>西游记</value>
<value>红楼梦</value>
<value>水浒传</value>
</array>
</property>
</bean>

✨List注入

<property name="hobbys">
<list>
<value>听歌</value>
<value>看电影</value>
<value>爬山</value>
</list>
</property>

✨Map注入

<property name="card">
<map>
<entry key="中国邮政" value="456456456465456"/>
<entry key="建设" value="1456682255511"/>
</map>
</property>

✨set注入

<property name="games">
<set>
<value>LOL</value>
<value>BOB</value>
<value>COC</value>
</set>
</property>

😎Bean的作用域

✨Singleton模式

        当一个bean 的作用域为 Singleton ,那么 Spring IoC 容器中只会存在一个共享的 bean 实例,并且所有对 bean的请求,只要 id 与该 bean 定义相匹配,则只会返回 bean 的同一实例。 Singleton是单例类型,就是 在创建起容器时就同时自动创建了一个bean 的对象,不管你是否使用,他都存在了,每次获取到的对象 都是同一个对象。注意,Singleton 作用域是 Spring 中的缺省作用域。要在 XML 中将 bean 定义成 singleton,可以这样配置:
<bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">

😎Prototype模式

        当一个bean 的作用域为 Prototype ,表示一个 bean 定义对应多个对象实例。 Prototype作用域的bean会 导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。 Prototype 是原型类型,它在我们创建容器的时候并没有实例化,而是 当我们获取bean 的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经 验,对有状态的bean 应该使用 prototype 作用域,而对无状态的 bean 则应该使用 singleton 作用域。在 XML中将 bean 定义成 prototype ,可以这样配置:
<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>
或者
<bean id="account" class="com.foo.DefaultAccount" singleton="false"/>

🎯自动装配

😎重点

  • 自动装配是使用spring满足bean依赖的一种方法
  • spring会在应用上下文中为某个bean寻找其依赖的bean
Spring bean 有三种装配机制,分别是:
        1. 在 xml 中显式配置;
        2. 在 java 中显式配置;
        3. 隐式的 bean 发现机制和自动装配。
这里我们主要讲第三种:自动化的装配 bean
Spring 的自动装配需要从两个角度来实现,或者说是两个操作:
  •      组件扫描(component scanning)spring会自动发现应用上下文中所创建的bean
  •      自动装配(autowiring)spring自动满足bean之间的依赖,也就是我们说的IoC/DI
组件扫描和自动装配组合发挥巨大威力,使的显示的配置降低到最少。
推荐不使用自动装配 xml 配置 , 而使用注解

😎byName

        autowire byName (按名称自动装配 )
        由于在手动配置xml 过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。
        采用自动装配将避免这些错误,并且使配置简单化。
测试:
1. 修改 bean 配置,增加一个属性 autowire="byName"
<bean id="user" class="com.aaa.pojo.User" autowire="byName">
<property name="str" value="qinjiang"/>
</bean>
当一个 bean 节点带有 autowire byName 的属性时。
1. 将查找其类中所有的 set 方法名,例如 setCat ,获得将 set 去掉并且首字母小写的字符串,即 cat
2. spring 容器中寻找是否有此字符串名称 id 的对象。
3. 如果有,就取出注入;如果没有,就报空指针异常。

😎byType

autowire byType ( 按类型自动装配 )
使用 autowire byType 首先需要保证:同一类型的对象,在 spring 容器中唯一。如果不唯一,会报不唯一 的异常。
测试:
<bean id="dog" class="com.aaa.pojo.Dog"/>
<bean id="cat" class="com.aaa.pojo.Cat"/>
<bean id="cat2" class="com.aaa.pojo.Cat"/>
<bean id="user" class="com.aaa.pojo.User" autowire="byType">
<property name="str" value="qinjiang"/>
</bean>

😎使用注解

Autowired

@Autowired 是按类型自动转配的,不支持 id 匹配。
需要导入 spring-aop 的包!
<context:annotation-config/>
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>
@Autowired(required = false)
private Cat cat;

Qualifier

@Autowired 是根据类型自动装配的,加上 @Qualifier 则可以根据 byName 的方式自动装配
@Qualifier 不能单独使用。
@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;

@Resource

@Resource 如有指定的 name 属性,先按该属性进行 byName 方式查找装配;
其次再进行默认的 byName 方式进行装配;
如果以上都不成功,则按 byType 的方式自动装配。
都不成功,则报异常。
@Resource
private Cat cat;
@Resource
private Dog dog;

😎小结

@Autowired@Resource异同:
        1. @Autowired与 @Resource 都可以用来装配 bean 。都可以写在字段上,或写在 setter 方法上。
        2. @Autowired默认按类型装配(属于 spring 规范),默认情况下必须要求依赖对象必须存在,如果 要允许null 值,可以设置它的 required 属性为 false ,如: @Autowired(required=false) ,如果我 们想使用名称装配可以结合@Qualifier 注解进行使用
        3. @Resource(属于 J2EE 复返),默认按照名称进行装配,名称可以通过 name 属性进行指定。如果 没有指定name 属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在 setter方法上默认取属性名进行装配。 当找不到与名称匹配的 bean 时才按照类型进行装配。但是 需要注意的是,如果name 属性一旦指定,就只会按照名称进行装配。
        它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired byType@Resource先 byName。

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

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

相关文章

LeetCode 101.对称二叉树 C写法

LeetCode 101.对称二叉树 C写法 思路&#xff1a; 将该树一分为二&#xff0c;左子树的左边与右子树的右边比&#xff0c;左子树的右边与右子树的左边比&#xff0c;不相等或者一边为空则不是对称。 代码&#x1f50e;&#xff1a; bool _isSymmetric(struct TreeNode* Leftroo…

程序员开发指南

在这个快节奏的时代&#xff0c;作为一名程序员&#xff0c;大家都希望能更快地开发出高质量的应用&#xff0c;而不是花费大量时间在基础设施和后台服务的搭建上。今天&#xff0c;我要向大家介绍一款专为懒人开发者准备的一站式开发应用的神器——MemFire Cloud。 一站式开发…

使用代理访问内网:实验二

目录 环境搭建 内网搭建&#xff08;win2019&#xff09; 跳板机搭建&#xff08;win10&#xff09; 实验步骤 1. win10上线kali 2. 借助msf做代理 3. 在攻击机上做个代理&#xff0c;访问目标网站 4. 使用SocksCap64工具&#xff0c;进行sock4a隧道的连接 5. 启用soc…

TypeScript 的主要特点和重要作用

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

最短路(dijkstra迪杰斯特拉)

最短路径问题在图论中是一个经典的问题&#xff0c;目的是找到从一个起始顶点到其他所有顶点的最短路径。Dijkstra算法是解决非负权图最短路径问题的常用算法。下面是一个使用Dijkstra算法解决最短路径问题的Java程序例子。 动画描述(从0节点开始更新) 问题描述 假设有一个图…

【机器学习西瓜书学习笔记——模型评估与选择】

机器学习西瓜书学习笔记【第二章】 第二章 模型评估与选择2.1训练误差和测试误差错误率误差 欠拟合和过拟合2.2评估方法留出法交叉验证法自助法 2.3性能度量查准率、查全率与F1查准率查全率F1 P-R曲线ROC与AUCROCAUC 代价敏感错误率与代价曲线代价曲线 2.4比较检验假设检验&…

VSCode+Vue3无法找到模块“../components/xxxxx.vue”的声明文件的错误

莫名奇妙的错误 今天用Vue3写个demo&#xff0c;在components下面新建了一个DeviceList.Vue的文件&#xff0c;在HomeView引用它后居然报错&#xff0c;提示&#xff1a;无法找到模块“…/components/DeviceList.vue”的声明文件&#xff0c;真是离了个大谱&#xff0c;文件明…

【Redis】 拓展:Redis - BigKey方案探讨

BigKey: 用户越多&#xff0c;redis数据越多&#xff0c;bigkey会使得缓存数据更大&#xff0c;网络带宽会被占用&#xff0c;执行效率就低下&#xff0c;高并发的时候吞吐量QPS也会下降。 产生原因&#xff1a; 看如下list&#xff1a; 一个key的内容太大&#xff0c;比如1M&…

VR舒适度术语表与检查表:为MR和空间计算应用创业者准备

随着混合现实&#xff08;MR&#xff09;和空间计算应用的发展&#xff0c;确保用户在虚拟环境中的舒适度变得尤为重要。本文将介绍一套专门针对VR舒适度的术语表&#xff0c;并提供两个知名VR游戏作为示例&#xff0c;来展示如何应用这些术语。这些术语和示例可以帮助开发者更…

基于Hadoop的服装电商数据分析系统【Hdfs、flume、HIve、sqoop、MySQL、echarts】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍总体研究方向数据集介绍配置flume文件HIve建表HIveSQL大数据分析MySQL建表Sqoop命令导出数据到MySQL数据可视化店铺销售情况.......等 总结每文一语 有需要本项目的代码或文档以及全…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十四)-租云服务器及配环境、docker基本命令

主要介绍了租云服务器和docker配置、基本命令&#xff01;&#xff01;&#xff01; 文章目录 前言 一、云平台 二、租云服务器及安装docker 1.阿里云 2.安装docker 三、docker命令 将当前用户添加到docker用户组 镜像&#xff08;images&#xff09; 容器(container) 四、实战…

Vue3-18 组件基础

组件的定义 我们在项目的src/components种定义组件&#xff0c;vue提供了几种简单的组件的定义方式 在单文件种定义组件 <script setup> import { ref } from vue const count ref(0) </script> <template><div>第一种<button click"count…

系统测试:验证系统整体行为的关键环节

目录 前言1. 系统测试的概念2. 系统测试的主要作用2.1 验证需求实现2.2 发现集成问题2.3 提高系统质量2.4 评估系统性能 3. 系统测试在整个测试过程中的地位3.1 单元测试3.2 集成测试3.3 系统测试3.4 验收测试 4. 常用的系统测试工具4.1 Selenium4.2 JMeter4.3 LoadRunner4.4 T…

高等数学 第七讲 一元函数积分学的概念和性质_不定积分_定积分_变限积分_反常积分

1.不定积分 文章目录 1.不定积分1.1 原函数1.1.1 原函数与不定积分的定义1.1.2 原函数存在定理 2.定积分2.1 定积分的定义2.2 定积分的精确定义2.3 定积分的几何意义2.4 定积分的存在定理2.5 定积分的性质 3.变限积分3.1 变限积分的定理3.2 变限积分的性质 4.反常积分(待更新) …

springboot集团门户网站--论文源码调试讲解

第2章 开发环境与技术 开发集团门户网站需要搭建编程的环境&#xff0c;也需要通过调查&#xff0c;对各个相关技术进行分析&#xff0c;选取适合本系统开发的技术与工具。 2.1 MySQL数据库 MySQL是一种具有安全系数、安全系数、混合开发性、高效化等特征的轻量关联数据库智…

2024.07纪念一 debezium : spring-boot结合debezium

使用前提&#xff1a; 一、mysql开启了logibin 在mysql的安装路径下的my.ini中 【mysqlid】下 添加 log-binmysql-bin # 开启 binlog binlog-formatROW # 选择 ROW 模式 server_id1 # 配置 MySQL replaction 需要定义&#xff0c;不要和 canal 的 slaveId 重复 参考gitee的项目…

mysql超大分页问题处理~

大家好&#xff0c;我是程序媛雪儿&#xff0c;今天咱们聊mysql超大分页问题处理。 超大分页问题是什么&#xff1f; 数据量很大的时候&#xff0c;在查询中&#xff0c;越靠后&#xff0c;分页查询效率越低 例如 select * from tb_sku limit 0,10; select * from tb_sku lim…

专治408开始的晚!8月一定要完成这些事!

八月份才开始408&#xff0c;那到考试最多也只有4-5个月的时间 别担心&#xff0c;可以复习两轮&#xff01; 其实我一直建议大家408复习三轮&#xff0c;但是如果时间不够&#xff0c;那就要在复习质量上下功夫&#xff01; 考408有一个好处&#xff0c;就是不用先确定学校…

【错误总结】Ubuntu系统中执行 sudo apt-get update报错

Ubuntu系统中执行 sudo apt-get update报错 命令行描述升级sudo报错并解决错误描述错误解决原因1&#xff1a;系统网络问题 原因2&#xff1a;设置清华源后/etc/apt/sources.list不匹配原因3&#xff1a;ubuntu自带的源/etc/apt/sources.list有问题 apt-get update成功log参考 …

【Story】《程序员面试的“八股文”辩论:技术基础与实际能力的博弈》

目录 程序员面试中的“八股文”&#xff1a;助力还是阻力&#xff1f;1. “八股文”的背景与定义1.1 “八股文”的起源1.2 “八股文”的常见类型 2. “八股文”的作用分析2.1 理论基础的评价2.1.1 助力2.1.2 阻力 3. 实际工作能力的考察3.1 助力3.2 阻力 4. 面试中的背题能力4.…