spring从入门到精通(spring学习笔记,持续更新中)

一.什么是spring?

Spring是分层的 Java SE/EE应用 **full-stack(全栈式)**轻量级开源框架。它的主要目标是让 Java 企业级应用开发变得更加容易,提供了一种综合的编程和配置模型。

提供了表现层 SpringMVC和持久层 Spring JDBC Template以及 业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。

举个例子:

你可以把 Spring 想象成一个超级工厂 和一个智能管家

在传统的程序开发中,如果你想用到一个对象(比如一个 UserService 对象),你需要自己亲手去 new 一个:

复制代码
UserService userService = new UserService();

这就像你想用一个玩具,需要自己去买零件、自己组装。当玩具很多、很复杂时,管理起来会非常麻烦。

而 Spring 这个"超级工厂"接管了所有对象的创建工作。你只需要告诉工厂:"我需要一个 UserService",工厂就会自动制造好(或找到)一个给你。你不需要关心它是怎么做的。

同时,Spring 也是一个"智能管家"。它不仅创建对象,还会自动帮你把对象之间的依赖关系处理好。比如,你的 UserService 需要依赖一个 UserMapper(用来访问数据库),管家会自动把创建好的 UserMapper "注入"到 UserService 里面去。这个过程就是 控制反转(IoC)依赖注入(DI),它是 Spring 框架最核心的基础。

综上所述:Spring 是一个通过控制反转和依赖注入来管理对象生命周期和关系,并提供了AOP、数据访问、Web开发等一系列强大功能的综合性企业级应用开发框架。

二.spring的核心思想特性以及体系结构

1.核心思想

(1)控制反转(IoC)

  • 传统开发(正转) :程序员在代码中主动 创建 (new) 和管理对象及其依赖关系。就像你自己动手造零件、组装汽车。

  • Spring(反转) :将创建和管理对象的控制权反转 给了 Spring 容器。你只需要"告诉"容器你需要什么(通过配置或注解),容器就会主动创建好对象,并将它依赖的其他对象"注入"给它。就像你把汽车设计图交给工厂,工厂自动为你生产并组装好整辆车。(实现方式:依赖注入)

  • 目的解耦。让程序组件之间不直接依赖,而是依赖于抽象,使得代码更灵活、更易于测试和维护。

(2)面向切面编程(AOP)

  • 核心问题 :在业务系统中,有很多横跨多个模块的通用功能(如日志、事务、安全校验)。如果把这些代码直接写在业务逻辑里,会导致代码冗余和混乱。

  • AOP 解决方案 :将这些横切关注点(通用功能)与核心业务逻辑分离,独立成一个"切面"。然后,在程序运行的合适时机,Spring 会像"插拔"一样,自动将这些切面功能织入到核心业务代码中。

  • 目的:让开发者能专注于核心业务,提高代码的模块化和可维护性。

二.IOC容器

* 传统方式

之前我们需要一个userDao实例,需要开发者自己手动创建 new UserDao();

* IOC方式

现在我们需要一个userDao实例,直接从spring的IOC容器获得,对象的创建权交给了spring控制

示例:实现service层与dao层代码解耦合

目录:

  1. 创建java项目,导入自定义IOC相关坐标

这三段配置合起来,就是告诉项目:我需要用 dom4j 处理 XML,用 jaxen 辅助查 XML 内容,再用 JUnit 做代码测试

2. 编写Dao接口和实现类


3. 编写Service接口和实现类


4. 编写测试代码


上面的service对象和dao对象耦合度太高,而且每次new的都是一个新的对象,导致服务器压力过大。

优化一下代码:

Beans.xml文件:

BeanFactory工具类

static代码块作用:初始化IOC容器,提前创建所有对象(在类被加载到内存时自动执行,且只执行一次。)就是在程序启动时,完成 "对象的批量创建和存储"。简单来说static块就像 "仓库管理员",在程序启动时按清(beans.xml)把所有需要的 "工具"(对象)提前造好,统一放进仓库(ioc map)里,后续用的时候直接拿,不用再临时造。

getBean方法的作用:从容器中获取对象是对外提供的 "取对象" 的接口,作用很直接:根据传入的beanId(就是<bean>标签里的id),从ioc map 中取出对应的对象返回。

修改Service接口和实现类

总结:

(一)初始耦合版本:硬编码创建对象(高耦合)

此版本中,对象由业务代码直接new创建,模块间依赖强绑定,执行逻辑如下:

  1. test 模块(测试入口)触发执行 测试类UserTest中的@Test注解方法testSave()是执行入口:

    • 第一步:new UserServiceImpl()------ 手动创建Service层实例(UserServiceImpl);

    • 第二步:调用userService.save()------ 触发Service层的业务逻辑。

  2. Service 模块调用 Dao 模块 UserServiceImplsave()方法中,通过硬编码 创建Dao层实例:

    • 执行userDao = new UserDaoImpl()------ 手动创建Dao层实例(UserDaoImpl);

    • 调用userDao.save()------ 触发Dao层的数据访问逻辑(输出 "保存成功了...")。

  3. 核心问题

    • 调用逻辑依赖 "硬编码":Service直接依赖Dao的具体实现类(UserDaoImpl),若Dao实现类变更(如换UserDaoImpl2),需修改Service代码;

    • 对象重复创建:每次调用save()都会new新的UserDaoImpl,增加服务器资源消耗。

(二)优化后 IOC 版本:容器管理对象(解耦)

此版本引入Utils模块(BeanFactory)和beans模块(beans.xml),将 "对象创建权转移到容器",执行逻辑分为 "容器初始化" 和 "业务调用" 两阶段:

阶段 1:容器初始化(程序启动时自动执行,仅 1 次)

Utils模块的BeanFactory静态代码块触发,核心是 "读取beans配置→解析→创建对象→存入容器":

  1. beans 模块(配置源)提供信息 beans.xml中通过<bean id="userDao" class="com.hhxy.Dao.impl.UserDaoImpl"/>定义:

    • idDao对象的唯一标识("userDao");

    • classDao实现类的全路径名(用于后续反射创建对象)。

  2. Utils 模块(IOC 容器)执行初始化 BeanFactory的静态代码块(程序启动时,BeanFactory类加载即执行):

    • 读配置:通过类加载器获取beans.xml输入流;

    • 解析 XML:用dom4j+jaxen解析,通过 XPath 表达式//bean定位所有<bean>标签;

    • 反射创建对象:通过Class.forName(className).newInstance(),根据class属性的全路径名,动态创建UserDaoImpl实例;

    • 存入容器:将 "id=userDaoUserDaoImpl实例" 存入静态Map<String, Object> iocMap作为 IOC 容器,实现对象复用)。

阶段 2:业务调用(测试触发,多次复用对象)

  1. test 模块(入口)触发执行 同初始版本,UserTest.testSave()new UserServiceImpl()(仅创建Service实例,不创建Dao实例),再调用userService.save()

  2. Service 模块调用 Utils 模块获取 Dao 对象 UserServiceImplsave()方法修改为:userDao = (UserDao) BeanFactory.getBean("userDao")------ 通过Utils模块的getBean()方法,从ioc容器中获取已创建好的UserDaoImpl实例(无需new)。

  3. Dao 模块执行逻辑 调用userDao.save(),执行Dao层数据访问逻辑,输出 "保存成功了..."。

相关推荐
Flittly16 小时前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
咖啡八杯1 天前
GoF设计模式——中介者模式
java·后端·spring·设计模式
Flittly3 天前
【AgentScope Java新手村系列】(14)人机交互
java·spring boot·spring
RainCity3 天前
Java Swing 自定义组件库分享(十二)
java·笔记·后端
唐青枫7 天前
Java Spring WebFlux 实战指南:用 Mono、Flux 和 WebClient 写响应式接口
java·spring
咖啡八杯8 天前
GoF设计模式——策略模式
java·后端·spring·设计模式
Flittly10 天前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
dunky10 天前
Spring 的三级缓存与循环依赖
后端·spring
LinXunFeng10 天前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
通信小呆呆15 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人