第一章:Spring 框架概述
1.1 Spring 框架的定義與背景
Spring 是一個開源的輕量級 Java 開發框架,于 2003 年由 Rod Johnson 創立,旨在解決企業級應用開發的復雜性。其核心設計思想是面向接口編程和松耦合架構,通過分層設計(如表現層、業務層、數據訪問層)實現各組件的獨立復用,并通過?控制反轉(IoC)?和?面向切面編程(AOP)?兩大核心技術簡化開發流程。
Spring 框架的定位是?Java SE/EE 全棧一站式框架,它不直接替代其他框架(如 MyBatis、Struts 等),而是通過集成機制整合各類技術,降低開發復雜度。
1.2 Spring 框架的核心優點
- 解耦與 IoC 管理
- Spring 作為 “對象工廠”,負責創建和管理對象的生命周期及依賴關系,開發者無需手動創建對象,而是通過配置或注解讓 Spring 注入依賴,大幅降低組件耦合度。
- AOP 編程支持
- 通過切面編程,將橫切關注點(如日志、事務、權限)與業務邏輯分離,避免代碼冗余,提升可維護性。
- 聲明式事務管理
- 無需手動編寫事務代碼,通過注解或配置即可實現事務的提交、回滾,簡化數據庫操作。
- 便捷的測試支持
- 集成 JUnit 4,通過注解(如?
@RunWith(SpringJUnit4ClassRunner.class)
)可直接測試 Spring 管理的組件。
- 集成 JUnit 4,通過注解(如?
- 框架集成能力
- 內置對主流框架(如 Hibernate、MyBatis、Spring MVC 等)的支持,通過配置即可完成整合。
- 簡化 JavaEE API 調用
- 對復雜的 JavaEE API(如 JDBC、JavaMail)進行封裝,提供更簡潔的接口,降低使用門檻。
第二章:Spring 的 IoC 核心技術
2.1 什么是 IoC(控制反轉)
IoC(Inverse of Control)即 “控制反轉”,指將對象的創建、初始化和依賴關系管理從應用代碼中剝離,轉由 Spring 容器負責。傳統開發中,對象的生命周期由代碼直接控制(如?new Object()
),而 IoC 框架通過配置或注解 “反轉” 了這種控制權,使應用代碼僅需關注業務邏輯,無需關心對象創建細節。
2.2 IoC 解決的核心問題:降低程序耦合度
- 傳統開發的耦合問題:
若類 A 依賴類 B,則 A 內部需直接創建 B 的實例(如?B b = new B();
),此時 A 與 B 強耦合,若 B 的實現類變更,A 的代碼也需修改。 - IoC 模式的改進:
通過 Spring 容器配置類 A 對類 B 的依賴,容器在創建 A 時自動注入 B 的實例(如通過構造器或 setter 方法)。此時 A 僅依賴 B 的接口,不關心具體實現,實現了接口與實現的解耦。
2.3 IoC 的實現方式:依賴注入(DI)
IoC 的核心實現機制是?依賴注入(Dependency Injection,DI),即 Spring 容器在創建對象時,將其依賴的組件通過以下方式注入:
- 構造器注入
- 通過類的構造方法傳入依賴對象。
- 示例(XML 配置):
<bean id="userService" class="com.example.UserService"><constructor-arg ref="userDao" /> </bean>
- Setter 方法注入
- 通過類的 setter 方法傳入依賴對象。
- 示例(注解方式):
@Service public class UserService {private UserDao userDao;@Autowiredpublic void setUserDao(UserDao userDao) {this.userDao = userDao;} }
2.4 IoC 容器的核心接口
- BeanFactory:Spring IoC 容器的基礎接口,定義了加載、創建、管理 Bean 的基本功能。
- ApplicationContext:BeanFactory 的子接口,擴展了國際化、事件發布、資源加載等功能,是 Spring 應用中常用的容器接口(如?
AnnotationConfigApplicationContext
)。
2.5 IOC的程序入門
創建Java工程,導入坐標依賴
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope>
</dependency></dependencies>
編寫接口和實現類,編寫具體的實現方法
packagecom.qcbyjy.service;?publicinterfaceUserService{?publicvoidhello();?}??packagecom.qcbyjy.service;?publicclassUserServiceImplimplementsUserService{@Overridepublicvoidhello(){System.out.println("HelloIOC!!");}}
編寫Spring核心的配置文件,在src目錄下創建applicationContext.xml的配置 文件,名稱是可以任意的,但是一般都會使用默認名稱。
<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--IOC管理bean--><beanid="userService"class="com.qcbyjy.service.UserServiceImpl"/></beans>
為什么class是impl而不是,userservice?
因為?ioc管理bean ,bean是類。必須要可以實例化才行。
怎么確認他是配置文件的?
通過最頂部的配置信息確認?
把log4j.properties的配置文件拷貝到resources目錄下,做為log4j的日志配置 文件。 編寫測試方法。
packagecom.qcbyjy.test;?importcom.qcbyjy.service.UserService;importorg.junit.Test;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;?publicclassDemo1{?/***入門程序
*/@Testpublicvoidrun1(){//使用Spring的工廠
ApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext.xml");//通過工廠獲得類:UserServiceuserService=(UserService)applicationContext.getBean("userService");userService.hello();}?}
2.6??IOC技術總結
ApplicationContext接口,工廠的接口,使用該接口可以獲取到具體的Bean對 象。該接口下有兩個具體的實現類。springCould配置中心 ClassPathXmlApplicationContext,加載類路徑下的Spring配置文件。 FileSystemXmlApplicationContext,加載本地磁盤下的Spring配置文件。
@Testpublic void run0(){ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService=context.getBean("userService",UserService.class);userService.hello();}@Testpublic void run1(){ApplicationContext context=new FileSystemXmlApplicationContext("D:\\Spring627\\src\\main\\resources\\applicationContext.xml");UserService userService=context.getBean("userService",UserService.class);userService.hello();}
?2.7?Spring框架的Bean管理的配置文件方式
?id屬性,Bean起個名字,在約束中采用ID的約束,唯一,取值要求:必須以字 母開始,可以使用字母、數字、連字符、下劃線、句話、冒號id:不能出現特殊 字符。
class屬性,Bean 對象的全路徑。
scope屬性,scope屬性代表Bean 的作用范圍。
singleton單例(默認值),最常用的方式。
prototype 多例
request應用在Web項目中,每次HTTP請求都會創建一個新的 Bean
session應用在Web項目中,同一個HTTP Session 共享一個 BeanBean對象的創建和銷毀的兩個屬性配置
說明:Spring初始化 bean 或銷毀 bean 時,有時需要作一些處理工作,因此spring可以在創建和拆卸bean 的時候調用 bean 的兩個生命周期方法
init-method,當bean 被載入到容器的時候調用 init-method 屬性指定的方法destroy-method,當bean 從容器中刪除的時候調用 destroy-method 屬性指定的方法
<bean id="userService" class="com.qcby.service.UserServiceImpl" scope="prototype" init-method="init" destroy-method="destory"/>
?singleton單例
@Testpublic void run2(){ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService=context.getBean("userService",UserService.class);UserService userService1=context.getBean("userService",UserService.class);System.out.println(userService);System.out.println(userService1);}
prototype 多例
2.8?實例化Bean對象的三種方式
默認是無參數的構造方法(默認方式,基本上使用)
<bean id="us" class="com.qcbyjy.service.UserServiceImpl" />
靜態工廠實例化方式
package com.qcbyjy.demo1;?import com.qcbyjy.service.UserService;import com.qcbyjy.service.UserServiceImpl;?/*** 靜態工廠方式
*/public class StaticFactory {?// 靜態工廠方式
public static UserService createUs(){System.out.println("通過靜態工廠的方式創建UserServiceImpl對
象...");// 編寫很多業務邏輯 權限校驗
returnnewUserServiceImpl();}?}?<beanid="us"class="com.qcbyjy.demo1.StaticFactory"factory-method="createUs"/>
實例工廠實例化方式
packagecom.qcbyjy.demo1;?importcom.qcbyjy.service.UserService;importcom.qcbyjy.service.UserServiceImpl;?/****動態工廠方式
**/publicclassDfactory{?publicUserServicecreateUs(){System.out.println("實例化工廠的方式...");returnnewUserServiceImpl();}?}?<beanid="dfactory"class="com.qcbyjy.demo1.Dfactory"/><beanid="us"factory-bean="dfactory"factory-method="createUs"/>
?第三章:DI依賴注入
3.1依賴注入的概述
IOC和DI的概念 IOC:InverseofControl,控制反轉,將對象的創建權反轉給Spring!! DI:DependencyInjection,依賴注入,在Spring框架負責創建Bean對象時, 動態的將依賴對象注入到Bean組件中!!
3.2屬性的set方法注入值
編寫屬性,提供該屬性對應的set方法,編寫配置文件完成屬性值的注入
packagecom.qcbyjy.service;?importcom.qcbyjy.dao.OrderDao;?publicclassOrderServiceImplimplementsOrderService{?//編寫成員屬性,一定需要提供該屬性的set方法
privateOrderDaoorderDao;//一定需要提供該屬性的set方法,IOC容器底層就通過屬性的set方法方式注
入值
publicvoidsetOrderDao(OrderDaoorderDao){this.orderDao=orderDao;}?//消息
privateStringmsg;//年齡
privateintage;?publicvoidsetMsg(Stringmsg){this.msg=msg;}?publicvoidsetAge(intage){this.age=age;}?@OverridepublicvoidsaveOrder(){System.out.println("業務層:保存訂單..."+msg+"-"+age);//調用
orderDao.saveOrder();}?}??packagecom.qcbyjy.dao;
?publicclassOrderDaoImplimplementsOrderDao{?@OverridepublicvoidsaveOrder(){System.out.println("持久層:保存訂單...");}?}??<!--DI:依賴注入--><beanid="os"class="com.qcbyjy.service.OrderServiceImpl"><propertyname="orderDao"ref="od"/><propertyname="msg"value="你好"/><propertyname="age"value="30"/></bean><beanid="od"class="com.qcbyjy.dao.OrderDaoImpl"></bean>
3.3 屬性構造方法方式注入值
對于類成員變量,構造函數注入。
packagecom.qcbyjy.demo2;?publicclassCar{?//名稱
privateStringcname;//金額
privateDoublemoney;?publicCar(Stringcname,Doublemoney){this.cname=cname;this.money=money;}?@OverridepublicStringtoString(){return"Car{"+"cname='"+cname+'\''+",money="+money+
'}';}?}?<beanid="car"class="com.qcbyjy.demo2.Car"><constructor-argname="cname"value="大奔"/><constructor-argname="money"value="400000"/></bean>
?3.4? 數組,集合(List,Set,Map),Properties 等的注入
packagecom.qcbyjy.demo3;?importjava.util.Arrays;importjava.util.List;importjava.util.Map;importjava.util.Properties;?publicclassCollectionBean{?//數組
privateString[]strs;publicvoidsetStrs(String[]strs){this.strs=strs;}?privateList<String>list;publicvoidsetList(List<String>list){this.list=list;}?privateMap<String,String>map;publicvoidsetMap(Map<String,String>map){this.map=map;}?privatePropertiesproperties;publicvoidsetProperties(Propertiesproperties){this.properties=properties;
}?@OverridepublicStringtoString(){return"CollectionBean{"+"strs="+Arrays.toString(strs)+",list="+list+",map="+map+",properties="+properties+'}';}}?<!--給集合屬性注入值--><beanid="collectionBean"class="com.qcbyjy.demo3.CollectionBean"><propertyname="strs"><array><value>美美</value><value>小鳳</value></array></property><propertyname="list"><list><value>熊大</value><value>熊二</value></list></property><propertyname="map"><map><entrykey="aaa"value="老王"/><entrykey="bbb"value="小王"/></map></property><propertyname="properties"><props><propkey="username">root</prop><propkey="password">123456</prop></props></property></bean>
第四章:多配置文件方式
4.1??多配置文件的加載方式
在src的目錄下又多創建了一個配置文件,現在是兩個核心的配置文件,那么加 載這兩個配置文件的方式有兩種!
主配置文件中包含其他的配置文件:<importresource="applicationContext2.xml"/>?
工廠創建的時候直接加載多個配置文件:ApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");