Springboot框架,【Spring框架】Spring中的DI介紹

 2023-11-19 阅读 27 评论 0

摘要:Spring中的DI介紹 DI(Dependency Injection),即“依賴注入”,組件之間依賴關系由容器在運行期決定,即容器動態的將某個依賴關系注入到組件當中。它是是 Spring 框架核心IOC技術的具體實現。 依賴注入是控制反轉最常用的方式,通過控

Spring中的DI介紹

DI(Dependency Injection),即“依賴注入”,組件之間依賴關系由容器在運行期決定,即容器動態的將某個依賴關系注入到組件當中。它是是 Spring 框架核心IOC技術的具體實現。

依賴注入是控制反轉最常用的方式,通過控制反轉可以減低計算機代碼之間的耦合度。通過控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體將其所依賴的對象的引用傳遞給它。也可以說,依賴被注入到對象中。

Springboot框架。DI理解的關鍵點“誰依賴誰,為什么需要依賴”

  • 誰依賴誰:應用程序依賴IOC容器。
  • 為什么需要以依賴:應用程序需要IOC容器來提供對象需要的外部資源。
  • 注入什么:注入某個對象所依賴的外部資源。

依賴關系的管理:

  • 依賴關系的管理都交給Spring來維護。
  • 在當前類需要用到其他類的對象,由Spring為我們提供,我們只需要在配置文件中說明。
  • 這種依賴關系的維護就叫做依賴注入

能夠注入的數據:

  • 基本類型和String。
  • 其他bean類型(在配置文件中或者注解配置過的bean)。
  • 復雜類型/集合類型。

Spring mvc,依賴注入的方式:

  • 基于配置的形式注入依賴;
  • 基于注解的形式注入依賴;

基于配置的形式注入依賴

基于配置的形式注入依賴主要有兩種方法:

  • 通過有參構造函數注入依賴;
  • 通過set方法注入依賴;
通過有參構造函數注入依賴
<?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-3.0.xsd"><!--依賴注入方式1:有參構造--><bean id="user" class="com.tulun.bean.User"><!--id屬性的注入--><constructor-arg name="id" value="22"></constructor-arg><!--name屬性的注入--><constructor-arg name="name" value="zhangsan"></constructor-arg></bean>
</beans>
  • 有參構造函數的依賴注入主要使用<Constructor-arg>標簽;

    • name屬性:表示類中的屬性名。
    • value屬性:當前屬性名賦值。
  • 中臺前端框架?在類中必須包含有參構造函數,且和構造函數保持參數一致。

public class User {private String id;private String name;//有參構造方法public User(String id, String name) {this.id = id;this.name = name;}
}
  • 代碼測試:
public class App {public static void main(String[] args) {//獲取IOC的容器ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//通過容器來獲取當前的對象User user = (User) applicationContext.getBean("user");System.out.println(user);}
}

在這里插入圖片描述

通過set方法注入依賴
<?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-3.0.xsd"><!--依賴注入方式2:set方法--><bean id="user" class="com.tulun.bean.User" ><!--id屬性注入--><property name="id" value="12"/><!--name屬性賦值--><property name="name" value="李四"/></bean>
</beans>
  • set方法注入依賴時,使用property標簽;

    • name屬性:表示類中的屬性名。
    • value屬性:表示當前屬性的賦值。
  • java中的框架,代碼測試:

public class App {public static void main(String[] args) {//獲取IOC的容器ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//通過容器來獲取當前的對象User user = (User) applicationContext.getBean("user");System.out.println(user);}
}

在這里插入圖片描述

  • 注入的屬性可以是基本的類型,也可以是集合類型,也可以是自定義類型。
<?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-3.0.xsd"><!--對象的注入--><!--在Person類中注入自定義的User--><bean id="users" class="com.tulun.bean.User"/><bean id="person" class="com.tulun.bean.Person" ><!--user屬性通過set方式注入--><!--value:會按照String類型的字符串做解析 ref:Spring中管理對象的ID名--><property name="user" ref="users"/></bean>
</beans>
  • 集合類型:
    • 注入List類型的依賴。
<?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-3.0.xsd"><!--List的注入--><bean id="person" class="com.tulun.bean.Person"><property name="list" ><list><value>hello</value><value>你好</value><value>1234</value></list></property></bean>
</beans>
  • 其他形式的集合配置。
<?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-3.0.xsd"><!--數組的注入--><bean id="person" class="com.tulun.bean.Person"><property name="list" ><!--array標簽:注入數組--><array><!--value是直接給定值--><value></value></array></property></bean><!--set的注入--><bean id="person" class="com.tulun.bean.Person"><property name="list" ><!--set標簽:注入set類型的集合--><set></set></property></bean><!--map的注入--><bean id="person" class="com.tulun.bean.Person"><property name="map" ><!--map標簽:注入Map類型的集合--><map><entry key="1" value="zhangsan"/></map></property></bean>
</beans>

基于注解的形式注入依賴

  • @Value:注入普通形式的依賴;
  • @Resource:注入對象類型;
  • @Autowired:注入對象類型;

使用注解方式注入依賴前提是Bean的裝配支持注解掃描

<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/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--開啟注解掃描: base-package(必填)指令包路徑: 會掃描類方法、屬性上是否有注解--><context:component-scan base-package="com.tulun.bean"></context:component-scan><!--掃描屬性上面的注解(不建議使用)--><context:annotation-config></context:annotation-config>
</beans>
@Value注解
@Component(value = "user")
public class User {@Value("1")private String id;@Value("張三")private String name;}
  • 注:使用@Value注解注入依賴前提是Bean的裝配支持注解掃描。
  • 代碼測試:
public class App{public static void main( String[] args ){//獲取IOC的容器ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//通過容器來獲取當前的對象User user = (User) applicationContext.getBean("user");System.out.println(user);}
}

Mybatis框架、在這里插入圖片描述

@Resource注解
@Autowired注解
@Component(value = "person")
public class Person {//自定義類型屬性//和@Resource功能一樣@Autowiredprivate User user;}
  • 代碼測試:
public class App{public static void main( String[] args ){//獲取IOC的容器ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//通過容器來獲取當前的對象Person person = (Person)applicationContext.getBean("person");System.out.println(person);}
}

在這里插入圖片描述

@Resource@Aoutowire的異同點:

  • 在Spring中,@Resource@Aoutowire都是做Bean的注入時使用,@Resource@Aoutowire是可以替換使用的。
  • 共同點:
    • @Resource@Aoutowire是可以作為注入屬性的修飾,在為接口僅有單一實現類時,兩個注解效果一樣,可互相替換,不影響使用。
  • 不同點:
    • @Resource 是Java中提供的注解,@Resource存在兩個屬性,分別為nametype
      • 在Spring中是通過name來解釋bean的名字,而type屬性則解析為bean的類型,所以如果使用name屬性時,使用byName自動注入策略,而使用type屬性是則使用byType自動注入策略,如果不指定name或者type屬性時,這時將通過反射機制使用byName 自動注入策略。
    • @Autowired是Spring 提供的注解,在Spring的2.5版本引入。
      • @Autowired只根據type進行注入,不會去匹配name,如果type無法識別中注入對象是,需要依賴@Qualifier或者是Primary注解一起修飾。

依賴的解析過程

VB中的框架。容器解析Bean的依賴過程:

  • ApplicationContext是通過配置元數據來創建個初始化的,這些元數據描述了所有的Bean,描述元數據可以通過XML,注解或者Java代碼來指定。
  • 對于每一個Bean,他的依賴使用注解,構造方法參數或者靜態工廠方法參數的形式來表達。Bean被創建后之后這些依賴會被提供給他。
  • 每一個屬性或者構造方法的參數所設定的值都需要給定其實際意義,或者是對容器內另一個Bean的引用。

容器在創建的時候,Spring容器會驗證每一個Bean的配置,在實際創建Bean之前,Bean的屬性是不會被設置的。Bean只會在需要他的時候被創建,創建Bean的過程有可能會引起一系列的Bean被創建,例如Bean的依賴,其依賴的依賴等等會被一起創建和分配。注意:此時依賴之間解析不匹配的問題有可能會出現,即會循環創建有影響的Bean。

循環依賴問題:

  • 例如:
class User{private Person person;
}
class Person{private User user;
}
  • 此時如果是通過構造方法的方式注入,就有可能造成無法解決的循環依賴。
  • 例如:ClassA需要通過構造方法注入一個ClassB的實例,classB同樣需要通過構造方法注入ClassA的實例,如果為ClassA和ClassB配置Bean并且相互注入,IOC容器在運行時會發現這個循環引用,并拋出異常:BeanCurrentlyInCreationException
  • 解決循環依賴的途徑需要去編輯代碼,讓這些類通過setter方法注入,避免使用構造方法注入。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/184295.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息