Spring 簡介和配置#
學習目標#
【應用】能夠獨立完成 springIOC 的快速入門
【應用】能夠掌握 spring 的 bean 標籤的配置
【應用】能夠獨立完成 bean 的對象屬性注入
【應用】能夠獨立完成 bean 的普通屬性注入
【理解】能夠獨立完成 bean 的集合屬性注入
1、Spring 概述#
1.1 spring 是什麼#
Spring 是分層的 Java SE/EE 應用 full-stack 輕量級開源框架,以 IoC(Inverse Of Control:反轉控制)和 AOP(Aspect Oriented Programming:面向切面編程)為內核。
提供了表現層 SpringMVC 和持久層 Spring JDBCTemplate 以及業務層事務管理等眾多的企業級應用技術,還能整合開源世界眾多著名的第三方框架和類庫,逐漸成為使用最多的 Java EE 企業應用開源框架。
1.2 Spring 發展歷程#
1997 年, IBM 提出了 EJB 的思想
1998 年,SUN 制定開發標準規範 EJB1.0
1999 年,EJB1.1 發布
2001 年,EJB2.0 發布
2003 年,EJB2.1 發布
2006 年,EJB3.0 發布
Rod Johnson 羅賓・約翰遜( Spring 之父)
Expert One-to-One J2EE Design and Development (2002) 闡述了 J2EE 使用 EJB 開發設計的優點及解決方案
Expert One-to-One J2EE Development without EJB (2004) 闡述了 J2EE 開發不使用 EJB 的解決方式(Spring 雛形)
2021 年 7 月份發布了 Spring 的最新版本 Spring 5.3.9 通用版(正式發布的版本)
1.3 Spring 的優勢 (理解)#
\1. 方便解耦,簡化開發#
Spring 就是一個大工廠(IoC 容器),可以將所有對象的創建和依賴關係的維護工作都交給 Spring 容器管理,大大地降低了組件之間的耦合性。
\2. AOP 編程的支持#
通過 Spring 的 AOP 功能,方便進行面向切面編程,許多不容易用傳統 OOP 實現的功能可以通過 AOP 輕鬆實現。
如 實現對程序進行權限攔截、運行監控等功能
\3. 聲明式事務的支持#
可以將我們從單調煩悶的事務管理代碼中解脫出來,通過聲明式方式靈活的進行事務管理,提高開發效率和質量。
\4. 方便程序的測試#
Spring 對 Junit4 支持,可以通過註解方便的測試 Spring 程序,測試不再是昂貴的操作,而是隨手可做的事情。
\5. 方便集成各種優秀框架#
Spring 不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持。
\6. 降低 JavaEE API 的使用難度#
Spring 對 JavaEE 開發中非常難用的一些 API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些 API 應用難度大大降低。
\7. Java 源碼是經典學習範例#
Spring 的源代碼設計精妙、結構清晰、匠心獨用,處處體現著大師對 Java 設計模式靈活運用以及對 Java 技術的高深造詣。它的源代碼無意是 Java 技術的最佳實踐的範例。
1.4 Spring 的體系結構(了解)#
2、Spring IoC 快速入門#
2.1 IoC 的概念和作用#
IoC:控制反轉 (Inversion Of Control),就是應用本身不負責依賴對象的創建及維護,依賴對象的創建及維護是由外部容器負責的。這樣控制權就由應用轉移到了外部容器,控制權的轉移就是所謂反轉。
簡單理解:把對象的創建、初始化、銷毀等工作交給 spring 容器來做。由 spring 容器控制對象的生命週期。
明確 IoC 的作用:削減計算機程序的耦合 (解除我們代碼中的依賴關係)。
原來:我們在獲取對象時,都是採用 new 的方式。 是主動的。
現在:我們獲取對象時,跟 spring 容器要,有 spring 為我們查找或者創建對象。 是被動的。
2.2 Spring IoC 程序開發步驟#
①導入 Spring 開發的基本包坐標
②編寫 Dao 接口和實現類
③創建 Spring 核心配置文件
④在 Spring 配置文件中配置 UserDaoImpl
⑤使用 Spring 的 API 獲得 Bean 實例
2.3 導入 Spring 開發的基本包坐標#
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring‐context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2.4 編寫 Dao 接口和實現類#
package com.summer.dao;
public interface UserDao {
public void save();
}
package com.summer.dao.impl;
import com.summer.dao.UserDao;
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("用戶添加~~~~~");
}
}
2.5 創建 Spring 核心配置文件#
在類路徑 classpath 下(resources)創建 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring‐beans.xsd">
</beans>
2.6 在 Spring 配置文件中配置 UserDaoImpl#
<?xml version="1.0" encoding="UTF‐8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema‐instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring‐beans.xsd">
<!‐‐ 實現IoC將對象的創建 交給spring容器
UserDao userDao = new UserDaoImpl();
‐‐>
<bean id="userDao" class="com.bailiban.dao.impl.UserDaoImpl"></bean>
</beans>
2.7 使用 Spring 的 API 獲得 Bean 實例#
public class TestIoC{
public static void main(String[] args) {
// 創建spring容器實例
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
//從容器中獲取 bean 根據 唯一標識id獲取
UserDao userDao = (UserDao) context.getBean("userDao");
userDao.save();
}
}
在類路徑下尋找配置文件來實例化容器
Spring 快速入門代碼鞏固練習
練習下通過 springIoC 的 XML 配置方式來進行對象的實例化
\1. 導入坐標
\2. 創建 Bean
\3. 創建配置文件 applicationContext.xml
\4. 在配置文件中進行配置
\5. 創建 ApplicationContext 對象 getBean
3、 Bean 的依賴注入入門#
① 編寫 Dao,Service 接口和實現類
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("用戶添加~~~~~");
}
}
public interface UserService {
public void save();
}
public class UserServiceImpl implements UserService {
public void save() {
//TODO
}
}
②將 UserDaoImpl 、 UserServiceImpl 的創建權交給 Spring
<
!‐‐ spring IoC 將對象的創建權交給spring‐‐>
<bean id="userDao" class="com.bailiban.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.bailiban.service.impl.UserServiceImpl"></bean>
UserService 內部再調用 UserDao 的 save () 方法
public class UserServiceImpl implements UserService {
public void save() {
//創建spring容器實例
ApplicationContext context = new ClassPathXmlApplicationContext();
//根據id獲取dao對象
UserDao userDao = (UserDao) context.getBean("userDao");
//調用方法
userDao.save();
}
}
③從 Spring 容器中獲得 UserService 進行操作
public class TestDI {
//測試 DI快速入門
@Test
public void test1() {
//創建spring容器實例
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
//根據id獲取dao對象
UserService userService = (UserService) context.getBean("userService");
//調用方法
userService.save();
}
}
3.1 Bean 的依賴注入分析#
目前 UserService 實例和 UserDao 實例都存在與 Spring 容器中,當前的做法是在容器外部獲得 UserService 實例和 UserDao 實例,然後在程序中進行結合。
因為 UserService 和 UserDao 都在 Spring 容器中,而最終程序直接使用的是 UserService,所以可以在 Spring 容器中,將 UserDao 設置到 UserService 內部。
3.2 Bean 的依賴注入概念#
DI : Dependency Injection 依賴注入,需要有 IoC 的環境,Spring 創建對象的過程中,Spring 將對象依賴的屬性注入到對象。
在編寫程序時,通過控制反轉,把對象的創建交給了 Spring,但是代碼中不可能出現沒有依賴的情況。
IoC 解耦只是降低他們的依賴關係,但不會消除。例如:業務層仍會調用持久層的方法。
那這種業務層和持久層的依賴關係,在使用 Spring 之後,就讓 Spring 來維護了。
簡單的說,就是坐等框架把持久層對象傳入業務層,而不用我們自己去獲取。
3.3 Bean 的依賴注入方式#
怎麼將 UserDao 怎樣注入到 UserService 內部呢?
3.3.2 set 方法#
在 UserServiceImpl 中添加 setUserDao 方法
public class UserServiceImpl implements UserService {
// 定義dao成員變量
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void save() {
// //創建spring容器實例
// ApplicationContext context = new
// ClassPathXmlApplicationContext("applicationContext.xml");
// //根據id獲取dao對象
// UserDao userDao = (UserDao) context.getBean("userDao");
// //調用方法
userDao.save();
}
}
配置 Spring 容器調用 set 方法進行注入
<bean id="userDao" class="com.bailiban.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.bailiban.service.impl.UserServiceImpl">
<!‐‐使用set方法注入
name: set方法去掉set後 首字母小寫
‐‐>
<property name="userDao" ref="userDao"></property>
</bean>
set 方法
命名空間注入P 命名空間注入本質也是 set 方法注入,但比起上述的 set 方法注入更加方便,主要體現在配置文件中,如下:
首先,需要引入 P 命名空間:
xmlns:p="http://www.springframework.org/schema/p"
其次,需要修改注入方式
<bean id="userService" class="com.bailiban.service.impl.UserServiceImpl" p:userDao‐
ref="userDao">
3.4 Bean 的依賴注入的數據類型#
上面的操作,都是注入的引用 Bean,除了對象的引用可以注入,普通數據類型 等都可以在容器中進行注入。
注入數據的二種數據類型
1. 普通數據類型
2. 引用數據類型
其中引用數據類型,此處就不再贅述了,之前的操作都是對 UserDao 對象的引用進行注入的,下面將以 set 方法注入為例,演示普通數據類型的注入。
Bean 的依賴注入的數據類型
(1)普通數據類型的注入
練習:
public class UserDaoImpl implements UserDao {
//普通數據類型的注入
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void save() {
System.out.println(name+"‐‐‐"+age);
System.out.println("用戶添加~~~~~");
}
}
<bean id="userDao" class="com.bailiban.dao.impl.UserDaoImpl">
<!‐‐ 普通數據的注入 ‐‐>
<property name="name" value="旺財"></property>
<property name="age" value="18"></property>
</bean>