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

🎼个人主页:【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://xiahunao.cn/news/3280007.html

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

相关文章

前端vue3 巧妙的checkbox 选中框样式

我们 做前端页面交互效果的时候 我们会使用到 checkbox 复选框 做一些交互的效果 我是用的是 nut-ui 组件库中的 checkbox 组件 类似于这样的选中效果 假如 二选一的那种 可以 这样写 交互好看 而不是单纯的 checkbox 框 这里我就不使用 gif 图片了 大家应该都可以看懂的 …

操作系统课程设计:(JAVA)进程管理系统(附源码zip,jdk11,IDEA Ultimate2024 )

一.题目要求描述 本设计的目的是加深对进程概念及进程管理各部分内容的理解&#xff1b;熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施。要求设计一个允许n个进程并发运行的进程管理模拟系统。 该系统包括有简单的进程控制、同步与…

Spring AOP总结

1、AOP&#xff08;Aspect-Oriented Programming&#xff09;&#xff1a;面向切面编程让开发更高效。 工作中经常需要处理日志记录、事物管理、安全控制等跨越多个业务模块的公共逻辑。 它是一种编程的范式。它通过将跨多个业务模块的公共逻辑抽取并封装成独立的模块&#xf…

微信小程序云开发订单微信支付与小票和标签打印的完整高效流程

一个字“全”&#xff01;&#xff01;&#xff01; 前言一、流程设定1、如何开通云支付流程2、以订单下单为例的支付流程2.1 业务场景介绍2.2 业务场景流程图 二、代码与代码文件组成1、页面JS2、云函数payPre3、支付回调函数pay_cb3.1 准备条件3.2 必要认知3.3 pay_cb 完整函…

Python使用pytest-benchmark做基准测试

安装pytest-benchmark pip install pytest-benchmark代码编写 导入pytest import pytest我们以“在120以内的正整数中找出和120互质的正整数&#xff0c;并统计个数和求和”为例&#xff0c;比较穷举和使用数学技巧完成该任务的性能。 def coprime_120_1():count 0sum 0f…

Java 8-函数式接口

目录 一、概述 二、 函数式接口作为方法的参数 三、函数式接口作为方法的返回值 四、 常用的函数式接口 简单总结 简单示例 4.1 Consumer接口 简单案例 自我练习 实际应用场景 多线程处理 4.2 Supplier接口 简单案例 自我练习 实际应用场景 配置管理 4.3 Func…

MindIE Service服务化集成部署通义千问Qwen模型

一、昇腾开发者平台申请镜像 登录Ascend官网昇腾社区-官网丨昇腾万里 让智能无所不及 二、登录并下载mindie镜像 #登录docker login -u XXX#密码XXX#下载镜像docker pull XXX 三、下载Qwen的镜像 使用wget命令下载Qwen1.5-0.5B-Chat镜像&#xff0c;放在/mnt/Qwen/Qwen1.5-…

将项目部署到docker容器上

通过docker部署前后端项目 前置条件 需要在docker中拉去jdk镜像、nginx镜像 docker pull openjdk:17 #拉取openjdk17镜像 docker pull nginx #拉取nginx镜像部署后端 1.打包后端项目 点击maven插件下面的Lifecycle的package 对后端项目进行打包 等待打包完成即可 2.将打…

源码搭建国内微短剧系统上架(微信抖音)所需资质全面解析

随着短视频和微短剧市场的持续升温&#xff0c;越来越多的企业和个人开始关注并尝试进入这一领域。微短剧以其短小精悍、内容丰富的特点&#xff0c;吸引了大量用户的关注。对于想要搭建并运营自己的微短剧系统的创业者来说&#xff0c;选择合适的平台以及准备必要的资质成为了…

Linux下文件编译器-GCC/G++

前言 本文介绍了c/c的编译过程以及gcc/g的时使用 一.c/c翻译的本质&#xff1a;将高级语言翻译成二进制 1&#xff09;程序翻译过程&#xff1a; &#xff08;1&#xff09;预处理&#xff08;头文件展开、宏替换、去注释、条件编译&#xff09;还是C语言代码 ​ …

ad9361 CTRL_OUT0~7对应能读到的状态

ad9361 CTRL_OUT对应能读到的状态

新手小白如何投放知乎信息流广告推广?

随着越来越多的企业开始寻求更有效的方式来触达目标客户&#xff0c;知乎作为一个集知识分享、社交互动于一体的平台&#xff0c;已经成为众多品牌青睐的广告投放渠道之一。特别是知乎的信息流广告&#xff0c;因其高度融合的内容形式和精准的目标用户定向&#xff0c;成为了品…

《计算机网络》(第8版)第五章 运输层 复习笔记

第五章 运输层 一、运输层协议概述 1 运输层的功能 从通信和信息处理角度讲&#xff0c;传输层向应用层提供服务&#xff0c;是面向通信的最高层&#xff0c;也是面 向用户功能的最底层&#xff0c;它的主要功能有&#xff1a; &#xff08;1&#xff09;提供用户进程之间的逻…

HTML基础1-文本级元素

HTML 简介 什么是 HTML&#xff1f; HTML (HyperText Markup Language) 是一种用于创建网页的标准标记语言。它通过使用一系列预定义的元素来描述文档的结构和外观&#xff0c; 您可以使用 HTML 来建立自己的 WEB 站点。 HTML 的作用 HTML 用于定义网页的结构&#xff0c;…

Openwrt接UVC摄像头丢帧分析

Openwrt接UVC摄像头&#xff0c;使用mjpg-streamer&#xff0c;此处默认已经移植成功。这里以Skylab的SKW99为例进行说明&#xff0c;SKW99为高通QCA9531的方案&#xff0c;CPU的频率为650MHz。最近在应用过程中&#xff0c;需求完成后&#xff0c;发现视频码流下降了&#xff…

入门 PyQt6 看过来(案例)16~ 竖状菜单

本文依照上一篇文章进行简单的拓展&#xff0c;做一个竖状的堆栈菜单。效果如下&#xff1a; ​ 首先我们先进行分析以&#xff0c;页面左侧是菜单栏&#xff0c;按照堆栈式列表展示&#xff0c;包含基本信息和编程语言&#xff08;仔细的你是否发现路老师文字写错了&#xff1…

【数据结构】链式二叉树的实现和思路分析及二叉树OJ

【数据结构】链式二叉树的实现和思路分析及二叉树OJ &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;数据结构 文章目录 【数据结构】链式二叉树的实现和思路分析及二叉树OJ前言一.链式二叉树的定义及结构二.链式二叉树的遍历2.1前序遍历2.2中…

汇昌联信数字做拼多多运营实力强吗?

拼多多作为中国领先的电商平台之一&#xff0c;其运营实力一直是业界关注的焦点。汇昌联信数字公司作为一家专注于电商运营的企业&#xff0c;其在拼多多平台上的表现如何&#xff0c;是否具备强大的运营能力&#xff0c;是本篇文章探讨的主题。 一、答案是肯定的&#xff0c;汇…

C++高性能通信:图形简述高性能中间件Iceoryx

文章目录 1. 概述2. 支持一个发布者多个订阅者2.2 Iceoryx为何不支持多个发布者发布到同一个主题 3. Iceoryx的架构和数据传输示意图3.1 发布者与订阅者的通信机制3.2 零拷贝共享内存通信机制 4. 使用事件驱动机制4.1 WaitSet机制4.2 Listener机制 5. 已知限制6. 参考 1. 概述 …

Python .whl 独立安装和全部依赖安装命令

以安装 Flask 为例&#xff1a; 1. 独立安装 pip install whl_files/Flask-1.1.2-py2.py3-none-any.whl 2. 安装 Flask 全部依赖包和自己 cd /path/to/flask/1.0 pip install --no-index --find-links/path/to/downloaded/files Flask1.1.2 cd /path/to/flask/2.0 pip install …