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
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86953.shtml
英文地址,請注明出處:http://en.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;在實例間不共…