javascript
【Spring】Spring的IOC依赖注入的四种方式
-
作者簡介:大家好,我是五度魚,一個普通的Java領域博主,不停輸出Java技術博客和干貨。
-
座右銘:鍥而不舍,金石可鏤。
-
個人主頁:五度魚學Java的主頁
文章目錄
- 前言
- 1. set注入
- 2. 構造注入
- 3. p命名空間注入
- 4. c命名空間注入
前言
??這幾天學了Spring6,感覺到了Spring的強大和便捷。其中的IOC設計原則對對象的處理真的是達到了出神入化的地步,省去了不停的創建對象的過程。寫此篇文章是為了總結一下IOC的四種屬性注入方式,也是為了以后可以翻看,每日溫習一遍,孔子說過:“溫故而知新,可以為師矣”。各位朋友們在瀏覽此篇博客時可以溫習一下IOC的知識。
1. set注入
??set注入是基于set方法注入的,它的底層是通過反射機制調用屬性對應的set方法給屬性賦值,這種方式必須要求屬性對外提供set方法,讓兩個對象之間產生關系。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.powernode</groupId><artifactId>spring6-002-dependency-injection</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><repositories><repository><id>repository.spring.milestone</id><name>Spring Milestone Repository</name><url>https://repo.spring.io/milestone</url></repository></repositories><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.0-M2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties></project> package com.powernode.spring6.dao;/*** @author 五度魚* @version 1.0* @className UserDao* @since 1.0**/ public class UserDao {public void insert(){System.out.println("正在保存用戶數據。");} } package com.powernode.spring6.service;import com.powernode.spring6.dao.UserDao;/*** @author 五度魚* @version 1.0* @className UserService* @since 1.0**/ public class UserService {private UserDao userDao;// 使用set方式注入,必須提供set方法。// 反射機制要調用這個方法給屬性賦值的。public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void save(){userDao.insert();} } <?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"><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/><bean id="userServiceBean" class="com.powernode.spring6.service.UserService"><property name="userDao" ref="userDaoBean"/></bean></beans> package com.powernode.spring6.test;import com.powernode.spring6.service.UserService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 五度魚* @version 1.0* @className DITest* @since 1.0**/ public class DITest {@Testpublic void testSetDI(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");UserService userService = applicationContext.getBean("userServiceBean", UserService.class);userService.save();} }運行結果:
?
實現原理:
- <?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"><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/><bean id="userServiceBean" class="com.powernode.spring6.service.UserService"><property name="userDao" ref="userDaoBean"/></bean></beans>
-
通過property標簽獲取到屬性名:userDao
通過屬性名推斷出set方法名:setUserDao
通過反射機制調用setUserDao()方法給屬性賦值
property標簽的name是屬性名。
property標簽的ref是要注入的bean對象的id。
(通過ref屬性來完成bean的裝配,這是bean最簡單的一種裝配方式。裝配指的是:創建系統組件之間關聯的動作)
(1)setUsername() 演變為 username
(2)setPassword() 演變為 password
(3)setUserDao() 演變為 userDao
(4)setUserService() 演變為 userService
2. 構造注入
核心原理:通過調用構造方法來給屬性賦值。
package com.powernode.spring6.dao;/*** @author 五度魚* @version 1.0* @className OrderDao* @since 1.0**/ public class OrderDao {public void deleteById(){System.out.println("正在刪除訂單。。。");} } package com.powernode.spring6.service;import com.powernode.spring6.dao.OrderDao;/*** @author 五度魚* @version 1.0* @className OrderService* @since 1.0**/ public class OrderService {private OrderDao orderDao;// 通過反射機制調用構造方法給屬性賦值public OrderService(OrderDao orderDao) {this.orderDao = orderDao;}public void delete(){orderDao.deleteById();} } <bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/> <bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--index="0"表示構造方法的第一個參數,將orderDaoBean對象傳遞給構造方法的第一個參數。--><constructor-arg index="0" ref="orderDaoBean"/> </bean> @Test public void testConstructorDI(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");OrderService orderServiceBean = applicationContext.getBean("orderServiceBean", OrderService.class);orderServiceBean.delete(); }運行結果如下:
如果構造方法有兩個參數:
package com.powernode.spring6.service;import com.powernode.spring6.dao.OrderDao; import com.powernode.spring6.dao.UserDao;/*** @author 五度魚* @version 1.0* @className OrderService* @since 1.0**/ public class OrderService {private OrderDao orderDao;private UserDao userDao;// 通過反射機制調用構造方法給屬性賦值public OrderService(OrderDao orderDao, UserDao userDao) {this.orderDao = orderDao;this.userDao = userDao;}public void delete(){orderDao.deleteById();userDao.insert();} }Spring配置文件:
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/><bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--第一個參數下標是0--><constructor-arg index="0" ref="orderDaoBean"/><!--第二個參數下標是1--><constructor-arg index="1" ref="userDaoBean"/> </bean><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>執行測試程序:
不使用參數下標,使用參數的名字可以嗎?
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/><bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--這里使用了構造方法上參數的名字--><constructor-arg name="orderDao" ref="orderDaoBean"/><constructor-arg name="userDao" ref="userDaoBean"/> </bean><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>執行測試程序:
不指定參數下標,不指定參數名字,可以嗎?
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/> <bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--沒有指定下標,也沒有指定參數名字--><constructor-arg ref="orderDaoBean"/><constructor-arg ref="userDaoBean"/> </bean><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>執行測試程序:
配置文件中構造方法參數的類型順序和構造方法參數的類型順序不一致呢?
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/><bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--順序已經和構造方法的參數順序不同了--><constructor-arg ref="userDaoBean"/><constructor-arg ref="orderDaoBean"/> </bean><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>執行測試程序:
通過測試得知,通過構造方法注入的時候:
- 可以通過下標
- 可以通過參數名
- 也可以不指定下標和參數名,可以類型自動推斷。
Spring在裝配方面做的比較健壯。
3. p命名空間注入
目的:簡化配置。
使用p命名空間注入的前提條件包括兩個:
- 第一:在XML頭部信息中添加p命名空間的配置信息:xmlns:p="http://www.springframework.org/schema/p"
- 第二:p命名空間注入是基于setter方法的,所以需要對應的屬性提供setter方法。
執行結果:
4. c命名空間注入
c命名空間是簡化構造方法注入的。
使用c命名空間的兩個前提條件:
第一:需要在xml配置文件頭部添加信息:xmlns:c=“http://www.springframework.org/schema/c”
第二:需要提供構造方法。
package com.powernode.spring6.beans;/*** @author 五度魚* @version 1.0* @className MyTime* @since 1.0**/ public class MyTime {private int year;private int month;private int day;public MyTime(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}@Overridepublic String toString() {return "MyTime{" +"year=" + year +", month=" + month +", day=" + day +'}';} } <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:c="http://www.springframework.org/schema/c"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"><!--<bean id="myTimeBean" class="com.powernode.spring6.beans.MyTime" c:year="1970" c:month="1" c:day="1"/>--><bean id="myTimeBean" class="com.powernode.spring6.beans.MyTime" c:_0="2008" c:_1="8" c:_2="8"/></beans> @Test public void testC(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-c.xml");MyTime myTimeBean = applicationContext.getBean("myTimeBean", MyTime.class);System.out.println(myTimeBean); }執行結果:
最后求個關注,點贊,收藏,謝謝!
總結
以上是生活随笔為你收集整理的【Spring】Spring的IOC依赖注入的四种方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos6.5 升级openssl1
- 下一篇: FreeRTOS系统下LwIP-1.4.