Spring核心框架完全指南 - 基础知识全解析

📖 目录

🌟 Spring框架简介

🏗️ IoC容器详解

💉 依赖注入(DI)深入理解

⚙️ Bean配置与管理

🎯 Bean的作用域

🔄 Bean生命周期

🎭 面向切面编程(AOP)

📝 Spring注解详解

📁 资源管理

📢 事件机制

🔤 SpEL表达式语言

🎯 实战案例

📚 总结


🌟 Spring框架简介

什么是Spring?

Spring就像是Java开发的"超级管家",它帮我们管理对象的创建、依赖关系,让我们专注于业务逻辑。

生活中的类比

  • 没有Spring = 自己管理家务(买菜、做饭、打扫、洗衣服...)
  • 有了Spring = 请了专业管家(告诉需求,管家安排一切)

Spring的核心优势

// 传统Java开发的痛点
public class TraditionalCode {public void businessLogic() {// 手动创建对象DatabaseConnection db = new DatabaseConnection();db.connect("localhost", "user", "password");UserDao userDao = new UserDao();userDao.setConnection(db); // 手动设置依赖EmailService emailService = new EmailService();emailService.setSmtpServer("smtp.gmail.com");UserService userService = new UserService();userService.setUserDao(userDao); // 手动装配userService.setEmailService(emailService);// 业务逻辑userService.registerUser("张三");// 手动清理资源db.close();}
}// Spring帮我们解决的问题
@Service
public class SpringCode {@Autowiredprivate UserService userService; // Spring自动注入public void businessLogic() {// 直接使用,专注业务逻辑userService.registerUser("张三");// Spring自动管理资源}
}

Spring的两大核心特性

  1. IoC(控制反转) - 对象的创建和管理交给Spring
  2. AOP(面向切面编程) - 横切关注点的统一处理

🏗️ IoC容器详解

什么是IoC(控制反转)?

控制反转就是把对象的控制权从程序员手中转移给Spring容器。

形象比喻

  • 传统方式 = 自己开车(需要关注启动、换挡、刹车等细节)
  • IoC方式 = 坐出租车(告诉目的地,司机负责驾驶)

IoC容器的类型

// 1. BeanFactory - 基础容器(懒加载)
public class BeanFactoryExample {public static void main(String[] args) {// 创建资源对象Resource resource = new ClassPathResource("applicationContext.xml");// 创建BeanFactoryBeanFactory factory = new XmlBeanFactory(resource);// 只有在获取Bean时才创建对象UserService userService = (UserService) factory.getBean("userService");}
}// 2. ApplicationContext - 高级容器(立即加载)
public class ApplicationContextExample {public static void main(String[] args) {// 启动时就创建所有单例BeanApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = context.getBean("userService", UserService.class);}
}

ApplicationContext的实现类

// 1. 从类路径加载XML配置
ApplicationContext context1 = new ClassPathXmlApplicationContext("applicationContext.xml");// 2. 从文件系统加载XML配置
ApplicationContext context2 = new FileSystemXmlApplicationContext("/path/to/applicationContext.xml");// 3. 基于注解的配置
ApplicationContext context3 = new AnnotationConfigApplicationContext(AppConfig.class);// 4. Web应用上下文
// 在web.xml中配置,由Spring自动创建

💉 依赖注入(DI)深入理解

什么是依赖注入?

依赖注入是IoC的具体实现方式,就是Spring容器自动为对象提供它所需要的依赖对象。

生活类比

  • 手动依赖 = 自己买零件组装电脑
  • 依赖注入 = 买品牌机(厂商已配好兼容硬件)

依赖注入的三种方式

1. 构造器注入(最推荐)
@Component
public class OrderService {// 使用final确保依赖不可变private final PaymentService paymentService;private final InventoryService inventoryService;private final NotificationService notificationService;// Spring会自动调用这个构造器public OrderService(PaymentService paymentService, InventoryService inventoryService,NotificationService notificationService) {this.paymentService = paymentService;this.inventoryService = inventoryService;this.notificationService = notificationService;}public void processOrder(Order order) {// 检查库存if (inventoryService.checkStock(order.getProductId(), order.getQuantity())) {// 处理支付Payment payment = paymentService.processPayment(order);if (payment.isSuccessful()) {// 发送通知notificationService.sendOrderConfirmation(order);}}}
}// 构造器注入的优点:
// 1. 确保依赖不为null(构造时必须提供)
// 2. 支持final字段(不可变性)
// 3. 便于单元测试
// 4. 避免循环依赖问题
2. Setter注入
@Component
public class UserService {private EmailService emailService;private SmsService smsService;private AuditService auditService;// Setter注入 - 可选依赖@Autowired(required = false) // 可选依赖public void setEmailService(EmailService emailService) {this.emailService = emailService;}@Autowiredpublic void setSmsService(SmsService smsService) {this.smsService = smsService;}@Autowiredpublic void setAuditService(AuditService auditService) {this.auditService = auditService;}public void registerUser(User user) {// 保存用户saveUser(user);// 发送邮件(如果可用)if (emailService != null) {emailService.sendWelcomeEmail(user.getEmail());}// 发送短信smsService.sendWelcomeSms(user.getPhone());// 记录审计日志auditService.logUserRegistration(user.getId());}
}// Setter注入的优点:
// 1. 支持可选依赖
// 2. 可以重新配置依赖
// 3. 适合有很多可选依赖的场景
3. 字段注入(简单但不推荐)
@Component
public class ProductService {@Autowiredprivate ProductRepository productRepository;@Autowiredprivate PriceCalculator priceCalculator;@Autowiredprivate InventoryChecker inventoryChecker;public Product getProduct(Long id) {Product product = productRepository.findById(id);product.setPrice(priceCalculator.calculatePrice(product));product.setInStock(inventoryChecker.isInStock(product.getId()));return product;}
}// 字段注入的缺点:
// 1. 难以进行单元测试
// 2. 不支持final字段
// 3. 隐藏了依赖关系
// 4. 可能导致空指针异常

依赖注入的高级特性

1. 按类型注入 vs 按名称注入
// 按类型注入(默认)
@Component
public class OrderService {@Autowiredprivate PaymentService paymentService; // 按PaymentService类型注入
}// 按名称注入
@Component
public class OrderService {@Autowired@Qualifier("creditCardPaymentService") // 指定Bean名称private PaymentService paymentService;
}// 或者使用@Resource
@Component
public class OrderService {@Resource(name = "creditCardPaymentService")private PaymentService paymentService;
}
2. 集合注入
@Component
public class NotificationService {// 注入所有MessageSender实现@Autowiredprivate List<MessageSender> messageSenders;// 注入所有MessageSender的Map,key为Bean名称@Autowiredprivate Map<String, MessageSender> messageSenderMap;public void sendNotification(String message) {// 使用所有可用的发送器for (MessageSender sender : messageSenders) {sender.send(message);}}
}// 实现类
@Component("emailSender")
public class EmailSender implements MessageSender {public void send(String message) {System.out.println("通过邮件发送: " + message);}
}@Component("smsSender")
public class SmsSender implements MessageSender {public void send(String message) {System.out.println("通过短信发送: " + message);}
}
3. 条件注入
@Component
@ConditionalOnProperty(name = "app.feature.email", havingValue = "true")
public class EmailService {public void sendEmail(String message) {System.out.println("发送邮件: " + message);}
}@Component
@Profile("dev") // 只在dev环境生效
public class MockPaymentService implements PaymentService {public Payment processPayment(Order order) {System.out.println("模拟支付处理");return new Payment(order.getAmount(), true);}
}@Component
@Profile("prod") // 只在生产环境生效
public class RealPaymentService implements PaymentService {public Payment processPayment(Order order) {// 真实的支付处理逻辑return processRealPayment(order);}
}

⚙️ Bean配置与管理

Bean的定义方式

1. XML配置方式
<!-- applicationContext.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"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 基本Bean定义 --><bean id="userService" class="com.example.UserService"><!-- 属性注入 --><property name="emailService" ref="emailService"/><property name="maxRetryCount" value="3"/></bean><!-- 构造器注入 --><bean id="orderService" class="com.example.OrderService"><constructor-arg ref="paymentService"/><constructor-arg ref="inventoryService"/><constructor-arg value="100"/></bean><!-- 集合属性注入 --><bean id="notificationService" class="com.example.NotificationService"><property name="senders"><list><ref bean="emailSender"/><ref bean="smsSender"/></list></property><property name="config"><map><entry key="retryCount" value="3"/><entry key="timeout" value="5000"/></map></property></bean><!-- 内部Bean --><bean id="userController" class="com.example.UserController"><property name="userService"><bean class="com.example.UserService"><property name="emailService" ref="emailService"/></bean></property></bean><!-- Bean别名 --><alias name="userService" alias="userManager"/><!-- 启用组件扫描 --><context:component-scan base-package="com.example"/></beans>
2. 注解配置方式
// 配置类
@Configuration
@ComponentScan(basePackages = "com.example")
@PropertySource("classpath:application.properties")
public class AppConfig {// 读取配置文件中的值@Value("${database.url}")private String databaseUrl;@Value("${database.username}")private String username;@Value("${database.password}")private String password;// 手动定义Bean@Beanpublic DataSource dataSource() {HikariDataSource dataSource = new HikariDataSource();dataSource.setJdbcUrl(databaseUrl);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}// Bean之间的依赖@Beanpublic UserRepository userRepository() {return new UserRepository(dataSource());}// 条件Bean@Bean@ConditionalOnMissingBean(EmailService.class)public EmailService defaultEmailService() {return new DefaultEmailService();}// 主要Bean(当有多个同类型Bean时的默认选择)@Bean@Primarypublic PaymentService primaryPaymentService() {return new CreditCardPaymentService();}
}
3. 组件注解
// 基础组件
@Component
public class FileProcessor {public void processFile(String filename) {System.out.println("处理文件: " + filename);}
}// 服务层组件
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public void saveUser(User user) {userRepository.save(user);}
}// 数据访问层组件
@Repository
public class UserRepository {@Autowiredprivate DataSource dataSource;public void save(User user) {// 数据库保存逻辑}
}// 控制层组件(虽然这里不讲SpringMVC,但展示注解)
@Controller
public class UserController {@Autowiredprivate UserService userService;
}

Bean的初始化和销毁

1. 注解方式
@Component
public class DatabaseConnection {private Connection connection;// 初始化方法@PostConstructpublic void init() {System.out.println("初始化数据库连接");// 建立数据库连接this.connection = DriverManager.getConnection("...");}// 销毁方法@PreDestroypublic void cleanup() {System.out.println("关闭数据库连接");try {if (connection != null && !connection.isClosed()) {connection.close();}} catch (SQLException e) {e.printStackTrace();}}
}
2. 接口方式
@Component
public class CacheManager implements InitializingBean, DisposableBean {private Map<String, Obje

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

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

相关文章

Parasoft C++Test软件集成测试(部件测试)_操作指南

系列文章目录 Parasoft C++Test软件静态分析:操作指南(编码规范、质量度量)、常见问题及处理 Parasoft C++Test软件单元测试:操作指南、实例讲解、常见问题及处理 Parasoft C++Test软件集成测试:操作指南、实例讲解、常见问题及处理 进阶扩展:自动生成静态分析文档、自动…

聊一聊 Linux 上对函数进行 hook 的两种方式

一&#xff1a;背景 1. 讲故事 前两篇我们介绍了 Minhook 在 Windows 平台上的强大功效&#xff0c;这一篇我们来聊一聊如何在 Linux 上对函数进行hook&#xff0c;这里介绍两种方式。 轻量级的 LD_PRELOAD 拦截 LD_PRELOAD是一种共享库拦截&#xff0c;这种方式的优点在于…

【免费分享】GWO-BP-AdaBoost预测!灰狼优化、人工神经网络与AdaBoost集成学习算法预测研究

一、模型组成原理 1. 灰狼优化算法&#xff08;GWO&#xff09; 核心思想&#xff1a;模拟灰狼群体的社会等级和狩猎行为&#xff08;包围、跟踪、攻击猎物&#xff09;&#xff0c;通过α、β、δ三级领导层引导种群搜索最优解。算法流程包括&#xff1a; 社会分层&#xff…

matlab实现非线性Granger因果检验

matlab程序包。用于格兰杰因果分析&#xff0c;分析数据时&#xff0c;直接带入数据即可。 hjt2/README , 1804 hjt2/c-code/Makefile , 57 hjt2/c-code/hjt2_tval.c , 10862 hjt2/matlab/spx_rp.dat , 175202 hjt2/matlab/spx_ur.dat , 174522 hjt2/matlab/spx_uv.dat , 1745…

从SQL Server到分布式大数据平台:重构企业数据架构

在企业数字化加速的背景下&#xff0c;越来越多的组织开始意识到&#xff1a;传统的数据系统正逐渐成为增长的“瓶颈”而非“助力”。其中&#xff0c;SQL Server 作为许多企业IT架构中曾经的中坚力量&#xff0c;正面临前所未有的挑战。它曾以稳定、易用、成本可控等优势&…

【网关】互联网公司的接入网关和业务网关怎么设计

网关 网关基础知识 RGW全称 Red GateWay :小红书网关&#xff08;网关英文&#xff1a;Gateway&#xff1b; 接入网关&#xff1a;Access Gateway&#xff09; 网关&#xff08;通用&#xff09;&#xff1a;Gateway 接入网关&#xff1a;API Gateway、Access Gateway 业务网关…

安全虚拟磁盘技术的创新与实践

文章目录 前言一、数据安全保护的新挑战1. 数据安全态势日益严峻&#xff0c;法律法规陆续出台2. 加强数据安全管控成为银行数据安全管理核心之一3. 银行终端数据安全管控存在的难题 二、安全虚拟磁盘的探索与实践1. 敏感文件的入盘及操作2. 敏感文件的流转及出盘三、安全虚拟磁…

uni-app项目实战笔记4--使用组件具名插槽slot定义公共标题模块

先来看效果&#xff1a; 如图&#xff0c;“每日推荐”&#xff0c;“专题精选”这些公共标题有相同的地方&#xff0c;也有自己的独特的地方&#xff0c;像这类有共性又有个性的可考虑使用slot插槽来实现。 实现步骤&#xff1a; 1.在前面文章创建的公共组件common-title定义…

Appium + Java 测试全流程

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】

vue3 双容器自动扩展布局 根据 内容的多少 动态定义宽度

需求&#xff1a; 左右两个列表 挨着排列&#xff0c;当左边内容超出滚动条时&#xff0c;换列显示&#xff0c;右边的列表随之移动 效果图&#xff1a; 1.左边数据&#xff1a;10&#xff0c;右边数据&#xff1a;5 2.左边数据&#xff1a;30&#xff0c;右边数据&#xff…

linux-java部署

version: 3 services:nacos_host:image: nacos/nacos-server:v2.2.0restart: alwayscontainer_name: nacos_hostenvironment:- MODEstandalone- PREFER_HOST_MODEhostnamevolumes:- ./sores/nacos/log:/home/nacos/logsports:- 8848:8848- 9848:9848 #2.0新增了两个端口&#x…

010502管道符_防火墙出入站_不回显带外-渗透命令-基础入门-网络安全

文章目录 1 管道符2 防火墙出入站3 不回显外带典型场景常见OOB通道实现示例&#xff08;以DNS为例&#xff09;1. 利用DNS外带数据2. 使用工具监听 防御建议扩展&#xff1a;无回显OOB自动化工具注意事项演示结语 1 管道符 | &#xff08;管道符号&#xff09; ||&#xff08;…

智慧养老与数字健康:科技赋能老年生活,构建全方位养老体系

在全球人口老龄化进程不断加速的当下&#xff0c;我国的老龄化程度也日益加深。 截至 2023 年末&#xff0c;我国 60 岁及以上人口达 2.97 亿人&#xff0c;占总人口的 21.1%&#xff0c;其中 65 岁及以上人口为 2.17 亿人&#xff0c;占总人口的 15.4%。 养老问题已成为全社…

在 cuda 基础环境中安装完整的cupy

nvidia/cuda:12.6.3-cudnn-devel-ubuntu22.04 1. 创建 cuda 基础容器 export NUM2 && \ sudo docker run --gpus all -it \ --name cupy_LHL_${NUM} \ -v /home/jimmy/ex_cupy/tmp${NUM}:/root/tmp${NUM} \ -v /home/jimmy/.ssh:/root/.ssh \ nvidia/cuda:12.6.3-dev…

OB Cloud × 海牙湾:打造高效灵活的金融科技 AI 数字化解决方案

在金融行业国产升级的战略背景下&#xff0c;上海海牙湾信息科技有限公司凭借其服务银行客户的深厚积累&#xff0c;近日完成重大技术升级 —— 将金融行业积分生态的SaaS平台、数字化营销中台及企业供应链管理系统全部迁移至完全自主研发的 OB Cloud 一体化云数据库。依托OB C…

LarkXR 赋能AI x XR数字供应链:引领智能设计、数字孪生与零售新未来

全球零售业数字化转型 在数字化浪潮的推动下&#xff0c;零售业正经历一场从设计到生产再到终端消费的全链路变革。消费者对个性化、沉浸式体验的需求日益增长&#xff0c;而企业也亟需通过数字化手段提升效率、降低成本并增强竞争力。Paraverse平行云的LarkXR实时云渲染技术&…

go语言快速入门

代码仓库 gitee 如何运行 以打印hello world为例 // main.go package main // package为main的文件可以直接运行import "fmt"func main() {fmt.Println("Hello, World!") }# 直接运行 go run main.go # 或者编译后运行 go build main.go ./main.exe变量…

使用麒麟V10操作系统的KVM服务,但麒麟V10存在高危漏洞无法修复?

麒麟V10操作系统之KVM部署虚拟机_麒麟v10安装kvm-CSDN博客文章浏览阅读3.7k次&#xff0c;点赞30次&#xff0c;收藏25次。本文介绍了在麒麟V10操作系统上部署KVM虚拟机的详细步骤&#xff0c;包括检查虚拟化支持、安装KVM组件、创建虚拟机、配置网络桥接&#xff0c;以及解决可…

PG、SprinBoot项目报错,表不存在

1、用户名密码错误 2、数据库IP和数据库名称错误 3、类似于如下的表结构 PG 默认扫描PUBLIC下面的表&#xff0c;需要手动指定schema&#xff0c;currentSchemaswdn_new url: jdbc:postgresql://${PGSQL_HOST:127.0.0.1}:${PGSQL_PORT:5432}/swdn_new?currentSchemaswdn_ne…

python类成员概要

python类成员概要 python类成员分类如图&#xff1a; 简要说明&#xff1a; 1.实例变量&#xff08;Instance Variables&#xff09; 定义&#xff1a;在方法中通过 self.变量名 声明&#xff0c;属于单个实例 特点&#xff1a;每个实例拥有独立副本&#xff0c;在实例间不共…