狂神说学习笔记:Spring
1|0Spring
1|11、Spring5
1.1、简介
- Spring:春天--->给软件行业带来了春天
- 2002年,Rod Jahnson首次推出了Spring框架雏形:interface21框架
- 2004年3月24日,Spring框架即以interface21框架为基础,经过重新设计,并不断丰富内涵,发布1.0正式版
- 很难想象创始人Rod Johnson的学历 , 他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学
- Spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架
- SSH:Strus2 + Spring + Hibernate
- SSM:SpringMvc + Spring +MyBatis
官方下载地址:Central Repository: org/springframework/spring (maven.org)
GitHub:Releases · spring-projects/spring-framework · GitHub
1.2、优点
- Spring是一个开源的免费的框架(容器)
- Spring是一个轻量级的、非入侵式的框架
- 控制反转(IOC:Inversion of Control),面向切面编程(AOP:Aspect Oriented Programming)
- 支持事务的处理,对框架整合的支持
Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
1.3、组成

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
- 核心容器(Spring Core):核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
- Spring 上下文(Spring Context):Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
- Spring面向切面编程(Spring AOP):通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。
- JDBC和DAO模块(Spring DAO):JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
- 对象实体映射(Spring ORM):Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
- Web模块(Spring Web):Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
- MVC模块(Spring Web MVC):MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
1.4、拓展
在Spring官网有这个介绍:现代化的Java开发!说白就是基于Spring的开发
- Spring Boot
- 一个快速开发的脚手架
- 基于SpringBoot可以快速的开发单个微服务
- 约定大于配置
- Spring Cloud
- SpringCloud是基于SpringBoot实现的
因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SpringMVC
弊端:发展了太久之后,违背了原来的理念!配置十分繁琐,人称:“配置地狱”
1|22、IOC理论推导
在以前的JAVAWEB设计中,我们通常分为Dao,Service,Servlet层。
但是在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改原代码,如果程序代码量十分大,修改一次的成本代价十分昂贵
最鲜明的例子是,当我们多个不同数据库获取和保存数据时,用户相对应操作的时候就需要我们更改我们目前代码操作的数据库对象(如Orcle和MySql的切换)
我们可以使用一个Set接口实现
即在需要不同的Dao层时,不需要更改Service层
- 之前,程序是主动创建对象!控制权在程序员手上!
- 使用Set注入后,程序不在具有主动性,而是变成了被动的接收对象
这种思想从本质上解决了问题,我们程序猿不再去管理对象的创建。系统耦合性大大下降,可以更加专注的 在业务层上的实现!这就是IOC的原型
2.1、IOC本质
控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
1|33、HelloSpring
基础配置文件:ApplicationContext.xml
IDEA创建方式:
实例化容器
ClassPathXmlApplicationContext
继承关系图(IDEA快捷键 Ctrl+H )
ClassPathXmlApplicationContext
父类关系图解(IDEA快捷键 Ctrl+Alt+U )

编写代码
-
编写一个Hello实体类
-
编写我们的spring文件 , 这里我们命名为
AppicationContext.xml
-
测试类
3.1、拓展
对spring-01-ioc
添加spring配置ApplicationContext.xml
:
测试类:
输出:
改变配置:
改变的输出:
3.2、思考问题
- Hello 对象是谁创建的 ?
- hello 对象是由Spring创建的
- Hello 对象的属性是怎么设置的 ?
- hello 对象的属性是由Spring容器设置的
这个过程就叫控制反转 :
- 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
- 反转 : 程序本身不创建对象 , 而变成被动的接收对象
- 依赖注入 : 就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收
可以通过new ClassPathXmlApplicationContext去浏览一下底层源码
OK , 到了现在 , 我们彻底不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !
1|44、IOC创建对象的方式
-
使用无参构造创建对象,默认
-
使用有参构造创建对象
-
下标赋值
-
类型赋值
-
参数名赋值
-
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了
1|55、Spring配置
5.1、别名Alias
5.2、Bean的配置
5.3、import
这个import,一般用于团队开发使用,它可以将多个配置文件,导入合并为一个
假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的
-
张三 beans.xml
-
李四 beans2.xml
-
王五 beans3.xml
-
applicationContext.xml
使用的时候,直接使用总的配置就可以了
1|66、依赖注入
6.1、构造器注入
6.2、Set方式注入【重点】
- 依赖注入(Dependency Injection,DI):Set注入!
- 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源
- 注入 : 指Bean对象所有属性 , 由容器来注入
【环境搭配】
-
复杂类型
Address.java
-
真实对象
Student.java
-
application.xml
-
测试类
6.3、拓展方式注入
我们可以使用p命令空间和c命令空间进行注入
官方解释:
使用!
测试
注意点:p命名和c命名空间不能直接使用,需要引入xml约束!
6.4、bean的作用域
-
单例模式(Spring默认机制)(适用于单线程)
-
原型模式:每次从容器中get的时候,都会产生一个新对象!(适用于多线程)
-
其余的request、session、application这些个只能在web开发中使用到
1|77、Bean的自动装配
- 自动装配是Spring满足bean依赖的一种方式
- Spring会在上下文自动寻找,并自动给bean装配属性
在Spring中有三种装配的方式
- 在xml中显式的配置
- 在Java中显式的配置
- 隐式的自动装配bean【重要】
7.1、测试
- 环境搭建
- 一个人有两个宠物
7.2、ByName自动装配
7.3、ByType自动装配
小结
- byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
- byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
7.4、使用注解实现自动装配
jdk1.5支持的注解,Spring2.5就支持注解了
The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.
要使用注解须知:
-
导入约束:context约束
-
配置注解的支持:
<context:annotation-config/>
@Autowired
直接在属性上使用即可!也可以在set方法上使用!
使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byName或byType!(默认使用byType,如果存在多个类型就byName)
-
情况1:
byType
-
情况2:
byType
-
情况3:先
byType
后byName
-
情况4:报错(解决:需要@Qualifier指定名字)
-
科普:
-
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifilter(value="xxx")去配合@Autowired的使用,指定一个唯一的bean对象注入
@Resource()
注:在jdk11后被移除
作用和@Autowired一样,但@Resource默认使用
byName
-
小结
@Resource 和 @Autowired
- 都是用来自动装配的,都可以放在属性字段上
- 实现方式不同:
- @Autowired默认通过
byType
的方式实现,如果有多个类型,则通过byName
实现,如果两个都找不到,就报错! - @Resource默认通过
byName
的方式实现,如果找不到名字,则通过byType
实现,如果两个都找不到,就报错!
- @Autowired默认通过
- 执行的顺序不同:
- @Autowired 默认通过
byType
的方式实现 - @Resource 默认通过
byName
的方式实现 - 类型重复的话,如果名字不是默认的(如cat11,cat111,而没有默认的cat)
- @Autowired 配合 @Qualifier(value = "cat11")使用
- @Resource 直接使用 @Resource(name = "cat11")
- @Autowired 默认通过
1|88、使用注解开发
在Spring4之后,要使用注解开发,必须要保证AOP的包导入了
使用注解需要导入context约束,增加注解的支持
-
bean
-
属性如何注入
-
衍生的注解
@Component有几个衍生的注解,我们在web开发中,会按照mvc三层架构分层!
- dao【@Repository】
- service【@Service】
- controller【@Controller】
这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean
-
自动装配
-
作用域
-
小结
xml 与 注解:
- xml 更加万能,适用于任何场合!维护简单方便
- 注解 不是自己的类使用不了,维护相对复杂
xml 与 注解 最佳实践:
-
xml用来管理bean
-
注解只负责完成属性的注入
-
我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解支持
1|99、使用Java的方式配置Spring
我们现在要完全不使用Spring的xml配置了,全权交给Java来做!
JavaConfig是Spring的一个子项目,在Spring4之后,它成为了一个核心功能!
实体类:
配置文件:
测试:
这种纯java的配置方式,在SpringBoot中随处可见!
1|1010、代理模式
为什么要学习代理模式?因为这就是SpringAOP的底层!【SpringAOP 和 SpringMVC】
代理模式的分类:
- 静态代理
- 动态代理
10.1、静态代理
角色分析:
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,一般会做些附属操作
- 客户:代理对象的人!
代理模式思想实现:
注意:代理模式 与 装饰者模式 的区别:面试官问:代理模式和装饰者模式有啥区别
代理模式的好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
- 公共业务就交给了代理角色,实现了业务的分工
- 公共业务发生拓展的时候,方便集中管理
缺点:
- 一个真实角色就会产生一个代理角色
- 代码量会翻倍,开发效率会变低
10.2、代理模式加深理解
代码:
-
接口
-
真实角色:改动原有的业务代码,在公司中是大忌!
-
需求来了,现在我们需要增加一个日志功能,怎么实现!
- 思路1 :在实现类上增加代码 【麻烦!】
- 思路2:使用代理来做,能够不改变原来的业务情况下,实现此功能就是最好的了!
-
设置一个代理类来处理日志!代理角色
-
客户端访问代理角色
我们在不改变原来的代码的情况下,实现了对原有功能的增强,这是AOP中最核心的思想
聊聊AOP:纵向开发,横向开发
10.3、动态代理
- 动态代理和静态代理角色一样
- 动态代理类是动态生成的,不是我们直接写好的
- 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
- 基于接口:JDK动态代理【我们在这里使用】
- 基于类:cglib
- java字节码实现:javassist
需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序
10.3.1、【InvocationHandler:调用处理程序】
10.3.2、【Proxy : 代理】
代码实现
Rent.java
Host.java
ProxyInvocationHandler.java
Client.java
10.3.3、深化理解
我们来使用动态代理实现代理我们后面写的UserService!
我们也可以编写一个通用的动态代理实现的类!所有的代理对象设置为Object即可!
测试
动态代理的好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
- 公共就交给代理角色!实现了业务的分工!
- 公共业务发生扩展的时候,方便集中管理!
- 一个动态代理类代理的是一个接口,一般就是对应的一类业务
- 一个动态代理类可以代理多个类,只要是实现了同一个接口即可【核心】
1|1111、AOP
11.1、什么是AOP
AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
11.2、Aop在Spring中的作用
提供声明式事务;允许用户自定义切面
以下名词需要了解下:
- 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....
- 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
Log
- 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
Log方法
- 目标(Target):被通知对象。
接口
- 代理(Proxy):向目标对象应用通知之后创建的对象。
代理类
- 切入点(PointCut):切面通知 执行的 “地点”的定义。
method
- 连接点(JointPoint):与切入点匹配的执行点。
invoke

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:
通知类型 | 连接点 | 实现接口 |
---|---|---|
前置通知 | 方法前 | org.springframework.aop.MethodBeforeAdvice |
后置通知 | 方法后 | org.springframework.aop.AfterReturningAdvice |
环绕通知 | 方法前后 | org.aopalliance.intercept.MethodInterceptor |
异常抛出通知 | 方法抛出异常 | org.springframework.aop.ThrowsAdvice |
引介通知 | 类中增加新的方法属性 | org.springframework.aop.IntroductionInterceptor |
即 Aop 在 不改变原有代码的情况下 , 去增加新的功能
11.3、使用Spring实现Aop
【重点】使用AOP织入,需要导入一个依赖包!
方式一:使用Spring的API接口【主要SpringAPI接口实现】
-
首先编写我们的业务接口和实现类
-
写我们的增强类 , 我们编写两个 , 一个前置增强 一个后置增强
-
在spring的文件中注册 , 并实现aop切入实现 , 注意导入约束
-
测试(注意:动态代理代理的是接口)
Aop的重要性 : 很重要 . 一定要理解其中的思路 , 主要是思想的理解这一块
Spring的Aop就是将公共的业务 (日志 , 安全等) 和领域业务结合起来 , 当执行领域业务时 , 将会把公共业务加进来 . 实现公共业务的重复利用 . 领域业务更纯粹 , 程序猿专注领域业务 , 其本质还是动态代理
方式二:自定义来实现【主要是切面定义】
-
写我们自己的一个切入类
-
去spring中配置
-
测试
方式三:使用注解实现!
-
编写一个注解实现的增强类
-
在Spring配置文件中,注册bean,并增加支持注解的配置
-
测试
1|1212、整合Mybatis
步骤:
-
导入相关jar包
-
junit
-
mybatis
-
mysql数据库:mysql-connector-java
-
spring相关的:spring-webmvc
-
aspectJ AOP 织入器
-
mybatis-spring整合包【重点】
-
配置Maven静态资源过滤问题!【约定大于配置】
-
-
编写配置文件
-
测试
12.1、回忆Mybatis
-
编写实体类
-
编写
db.properties
存放数据库 -
编写核心配置文件
-
编写接口
-
编写Mapper.xml
-
测试
12.2、Mybatis-Spring
什么是 MyBatis-Spring?
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中
知识基础
在开始使用 MyBatis-Spring 之前,你需要先熟悉 Spring 和 MyBatis 这两个框架和有关它们的术语。这很重要——因为本手册中不会提供二者的基本内容,安装和配置教程。
MyBatis-Spring 需要以下版本:
MyBatis-Spring | MyBatis | Spring Framework | Spring Batch | Java |
---|---|---|---|---|
2.0 | 3.5+ | 5.0+ | 4.0+ | Java 8+ |
1.3 | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
如果使用 Maven 作为构建工具,仅需要在 pom.xml 中加入以下代码即可:
12.2.1、整合方式一
-
引入配置文件
-
编写数据源配置
写法一:
写法二:导入
db.properties
注:
db.properties
中${username}不会被识别出来,会获取系统用户名,一直报错,建议使用${user} -
sqlSessionFactory
-
sqlSessionTemplate
-
需要给接口加实现类【新加的】
-
将自己写的实现类,注入到Spring中
-
测试
结果成功输出!现在我们的Mybatis配置文件的状态!发现都可以被Spring整合!
为了给mybatis-config.xml
留点面子(使用方便),在其中将别名和设置留下来
拓展
可以把spring-dao.xml
提取为配置文件,创建一个applicationContext.xml
注册 bean,在applicationContext.xml
里利用 import
标签导入spring-dao.xml
12.2.2、整合实现二
mybatis-spring1.2.3版以上的才有这个
dao继承Support类 , 直接利用 getSqlSession() 获得 , 然后直接注入SqlSessionFactory . 比起方式1 , 不需要管理SqlSessionTemplate , 而且对事务的支持更加友好 . 可跟踪源码查看
测试:
-
创建一个新的实现类
UserMapperImpl2
-
将该实现类,注入到Spring中
-
测试
总结 : 整合到spring以后可以完全不要mybatis的配置文件,除了这些方式可以实现整合之外,我们还可以使用注解来实现,这个等我们后面学习SpringBoot的时候还会测试整合!
1|1313、声明式事务
13.1、回顾事务
- 把一组业务当成一个业务来做;要么都成功,要么都失败!
- 事务在项目开发中,十分重要,涉及到数据的一致性问题,不能马虎
- 确保完整性和一致性
事务的ACID原则
- 原子性(atomicity)
- 事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用
- 一致性(consistency)
- 一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中
- 隔离性(isolation)
- 多个业务可能操作同一个资源,防止数据损坏
- 持久性(durability)
- 事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中!
13.2、Spring中的事务管理
-
声明式事务:AOP
- 一般情况下比编程式事务好用。
- 将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。
- 将事务管理作为横切关注点,通过aop方法模块化。Spring中通过Spring AOP框架支持声明式事务管理
-
编程式事务:需要在代码中,进行事务的管理
- 将事务管理代码嵌到业务方法中来控制事务的提交和回滚
- 缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码
-
使用Spring管理事务,注意头文件的约束导入 : tx
-
事务管理器
- 无论使用Spring的哪种事务管理策略(编程式或者声明式)事务管理器都是必须的。
- 就是 Spring的核心事务管理抽象,管理封装了一组独立于技术的方法。
-
JDBC事务
-
配置事务通知
-
spring事务传播特性
事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行为:
- propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
- propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
- propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
- propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
- propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
- propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作
-
-
配置AOP(导入aop的约束)
思考:
为什么需要事务?
- 如果不配置,可能存在数据提交不一致的情况;
- 如果我们不在Spring中去配置声明式事务,我们需要在代码中手动配置事务!
- 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎!
__EOF__

本文链接:https://www.cnblogs.com/dt746294093/p/16768002.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署