1. 程式人生 > >Spring的三種依賴注入方式

Spring的三種依賴注入方式

平常的java開發中,程式設計師在某個類中需要依賴其它類的方法,則通常是new一個依賴類再呼叫類例項的方法,這種開發存在的問題是new的類例項不好統一管理,spring提出了依賴注入的思想,即依賴類不由程式設計師例項化,而是通過spring容器幫我們new指定例項並且將例項注入到需要該物件的類中。依賴注入的另一種說法是“控制反轉”,通俗的理解是:平常我們new一個例項,這個例項的控制權是我們程式設計師,而控制反轉是指new例項工作不由我們程式設計師來做而是交給spring容器來做。

spring有多種依賴注入的形式,下面僅介紹spring通過xml進行IOC配置的方式:
  • Set注入
這是最簡單的注入方式,假設有一個SpringAction,類中需要例項化一個SpringDao物件,那麼就可以定義一個private的SpringDao成員變數,然後建立SpringDao的set
方法(這是ioc的注入入口):

package com.bless.springdemo.action;
public class SpringAction {
        //注入物件springDao
	private SpringDao springDao;
        //一定要寫被注入物件的<span class="KSFIND_CLASS" id="2KSFindDIV">set</span>方法
        public void <span class="KSFIND_CLASS" id="3KSFindDIV">set</span>SpringDao(SpringDao springDao) {
		this.springDao = springDao;
	}

        public void ok(){
		springDao.ok();
	}
}
隨後編寫spring的xml檔案,<bean>中的name屬性是class屬性的一個別名,class屬性指類的全名,因為在SpringAction中有一個公共屬性Springdao,所以要在<bean>標籤中建立一個<property>標籤指定SpringDao。<property>標籤中的name就是SpringAction類中的SpringDao屬性名,ref指下面<bean name="springDao"...>,這樣其實是spring將SpringDaoImpl物件例項化並且呼叫SpringAction的setSpringDao方法將SpringDao注入
<!--配置bean,配置後該類由spring管理-->
	<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
		<!--(1)依賴注入,配置當前類中相應的屬性-->
		<property name="springDao" ref="springDao"></property>
	</bean>
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>
  • 構造器注入
這種方式的注入是指帶有引數的建構函式注入,看下面的例子,我建立了兩個成員變數SpringDao和User,但是並未設定物件的set方法,所以就不能支援第一種注入方式,這裡的注入方式是在SpringAction的建構函式中注入,也就是說在建立SpringAction物件時要將SpringDao和User兩個引數值傳進來:

public class SpringAction {
//注入物件springDao
private SpringDao springDao;
private User user;

public SpringAction(SpringDao springDao,User user){
this.springDao = springDao;
this.user = user;
System.out.println("構造方法呼叫springDao和user");
}
        
        public void save(){
user.setName("卡卡");
springDao.save(user);
}
}
在XML檔案中同樣不用<property>的形式,而是使用<constructor-arg>標籤,ref屬性同樣指向其它<bean>標籤的name屬性:

<!--配置bean,配置後該類由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
<!--(2)建立構造器注入,如果主類有帶參的構造方法則需新增此配置-->
<constructor-arg ref="springDao"></constructor-arg>
<constructor-arg ref="user"></constructor-arg>
</bean>
        <bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>
         <bean name="user" class="com.bless.springdemo.vo.User"></bean>

<!--配置bean,配置後該類由spring管理-->
	<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
		<!--(2)建立構造器注入,如果主類有帶參的構造方法則需新增此配置-->
		<constructor-arg ref="springDao"></constructor-arg>
		<constructor-arg ref="user"></constructor-arg>
	</bean>
        <bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>
         <bean name="user" class="com.bless.springdemo.vo.User"></bean>
解決構造方法引數的不確定性,你可能會遇到構造方法傳入的兩引數都是同類型的,為了分清哪個該賦對應值,則需要進行一些小處理: 下面是設定index,就是引數位置:
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
		<constructor-arg index="0" ref="springDao"></constructor-arg>
		<constructor-arg index="1" ref="user"></constructor-arg>
	</bean>
PS:bean id 和 bean name到底有什麼區別呢?

Google和百度都找不到我想要的答案,最後還是在spring的官網上找到了如下的解釋,我自己理解為:bean name的定義是合法的,但是一個bean name不能唯一的代表一個bean,也就是多個bean可以擁有相同的bean name,但是bean id是唯一標示一個bean的,所以我們應該儘量避免用bean name來引用bean。

  • 自動注入

在一個稍大的專案中,如果元件採用xml的bean定義來配置,顯然會增加配置檔案的體積,查詢以及維護起來也不太方便。 Spring2.5為我們引入了元件自動掃描機制,他在類路徑下尋找標註了上述註解的類,並把這些類納入進spring容器中管理。它的作用和在xml檔案中使用bean節點配置元件時一樣的。要使用自動掃描機制,我們需要開啟以下配置資訊:

<?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/beans
			    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-2.5.xsd"> 
   
	<context:component-scan base-package=”com.eric.spring”>   
</beans> 

.component-scan標籤預設情況下自動掃描指定路徑下的包(含所有子包),將帶有@Component、@Repository、@Service、@Controller標籤的類自動註冊到spring容器。對標記了 Spring's @Required、@Autowired、JSR250's @PostConstruct、@PreDestroy、@Resource、JAX-WS's @WebServiceRef、EJB3's @EJB、JPA's @PersistenceContext、@PersistenceUnit等註解的類進行對應的操作使註解生效(包含了annotation-config標籤的作用)。

把DAO實現類注入到action的service介面(注意不要是service的實現類)中,注入時不要new 這個注入的類,因為spring會自動注入,如果手動再new的話會出現錯誤,然後屬性加上@Autowired後不需要getter()和setter()方法,Spring也會自動注入。在介面前面標上@Autowired註釋使得介面可以被容器注入,getBean的預設名稱是類名(頭字母小寫),如果想自定義,可以@Service(“aaaaa”)這樣來指定。這種bean預設是“singleton”的,如果想改變,可以使用@Scope(“prototype”)來改變。

可以使用以下方式指定初始化方法和銷燬方法:

@PostConstruct
public void init() { 
} 
@PreDestroy
public void destory() { 
} 
  使用Spring2.5的新特性——Autowired可以實現快速的自動注入,而無需在xml文件裡面新增bean的宣告,大大減少了xml文件的維護。(偶喜歡這個功能,因為偶對xml不感冒)。       以下是一個例子:
先編寫介面Man:
public interface Man {
      public String sayHello();
}
然後寫Man的實現類Chinese和American:
       @Service
public class Chinese implements Man{
    public String sayHello() {
        return "I am Chinese!";
    }
}
       @Service
public class American implements Man{
    public String sayHello() {
        return "I am American!";
    }
}

@Service註釋表示定義一個bean,自動根據bean的類名例項化一個首寫字母為小寫的bean,例如Chinese例項化為chinese,American例項化為american,如果需要自己改名字則:@Service("你自己改的bean名")。

beans.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/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
      <context:annotation-config/>
      <context:component-scan base-package="testspring.main"/>
</beans>

在spring的配置檔案裡面只需要加上<context:annotation-config/>和<context:component-scan base-package="需要實現注入的類所在包"/>,可以使用base-package="*"表示全部的類。

編寫主類測試:

@Service
public class Main {
    @Autowired
    @Qualifier("chinese")
    private Man man;

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        Main main = (Main) ctx.getBean("main");
        System.out.println(main.getMan().sayHello());
    }

    public Man getMan() {
        return man;
    }
}
在Man介面宣告的前面標上@Autowired和@Qualifier註釋使得Man介面可以被容器注入,當Man介面存在兩個實現類的時候必須指定其中一個來注入,使用實現類首字母小寫的字串來注入。否則可以省略,只寫@Autowired 。
註釋配置相對於 XML 配置具有很多的優勢:
它可以充分利用 Java 的反射機制獲取類結構資訊,這些資訊可以有效減少配置的工作。如使用 JPA 註釋配置 ORM 對映時,我們就不需要指定 PO 的屬性名、型別等資訊,如果關係表字段和 PO 屬性名、型別都一致,您甚至無需編寫任務屬性對映資訊——因為這些資訊都可以通過 Java 反射機制獲取。 

註釋和 Java 程式碼位於一個檔案中,而 XML 配置採用獨立的配置檔案,大多數配置資訊在程式開發完成後都不會調整,如果配置資訊和 Java 程式碼放在一起,有助於增強程式的內聚性。而採用獨立的 XML 配置檔案,程式設計師在編寫一個功能時,往往需要在程式檔案和配置檔案中不停切換,這種思維上的不連貫會降低開發效率。 

相關推薦

Spring-依賴注入方式

            三種依賴注入方式,即構造方法注入(constructor injection),setter方法注入(setter injection)以及介面注入(interface inj

深入淺出spring IOC中依賴注入方式

首先:第一個問題,參與者都有誰?1)物件2)IOC/DI容器3)某個物件的外部資源第二問題:依賴,誰依賴誰?為什麼需要依賴?依賴嘛,很好理解的,物件依賴於IOC/DI容器,至於為什麼要依賴呢?物件需要IOC/DI容器來提供物件需要的外部資源。第三個問題:注入,誰注入誰?又注入了什麼呢?顯而易見是IOC/DI容

Spring IOC(控制反轉)的依賴注入方式

1)、什麼是依賴注入(DI)和控制反轉(IOC) 依賴注入和控制反轉是對同一件事情的不同描述,從某個方面來講,就是他們描述的角度不同。 依賴注入是從應用程式的角度在描述,應用程式依賴容器建立並注入它所需要的外部資源; 控制反轉是從容器的角度在描述,描述完整點:容器控制應用程式,由容器反向的嚮應

控制反轉IOC的依賴注入方式 【調侃】IOC前世今生 IoC模式 談談對Spring IOC的理解 一個簡單的小程式演示Unity的三種依賴注入方式 小菜學習設計模式(五)—控制反轉(Ioc) IoC模式(依賴依賴倒置、依賴注入、控制反轉) IoC模式

轉自:https://www.cnblogs.com/ysyn/p/5563256.html 引言:    專案中遇到關於IOC的一些內容,因為和正常的邏輯程式碼比較起來,IOC有點反常。因此本文記錄IOC的一些基礎知識,並附有相應的簡單例項,而在實際專案中再複雜的應用也只是在

spring IOC中依賴注入方式 經典總結

首先:第一個問題,參與者都有誰?1)物件2)IOC/DI容器3)某個物件的外部資源第二問題:依賴,誰依賴誰?為什麼需要依賴?依賴嘛,很好理解的,物件依賴於IOC/DI容器,至於為什麼要依賴呢?物件需要IOC/DI容器來提供物件需要的外部資源。第三個問題:注入,誰注入誰?又注入了什麼呢?顯而易見是IOC/DI容

Spring依賴注入方式

平常的java開發中,程式設計師在某個類中需要依賴其它類的方法,則通常是new一個依賴類再呼叫類例項的方法,這種開發存在的問題是new的類例項不好統一管理,spring提出了依賴注入的思想,即依賴類不由程式設計師例項化,而是通過spring容器幫我們new指定例項並且將例項

Spring學習(十八)Bean 的依賴注入方式介紹

依賴注入:讓呼叫類對某一介面實現類的依賴關係由第三方注入,以移除呼叫類對某一介面實現類的依賴。 接下來將詳細的向大家介紹Spring容器支援的三種依賴注入的方式以及具體配置方法: •    屬性注入方

spring常用注入方式的測試與總結

spring三種常用注入方式 setter方法注入 欄位注入(註解實現) 構造器注入 1、setter方法注入 建立一個介面: public interface Axe { public String chop();

Spring依賴注入方式的比較

  我們知道,Spring物件屬性的注入方式有兩種:設值注入和構造注入。先看程式碼:   假設有個類為People,該物件包含三個屬性,name和school還有age,這些屬性都有各自的setter和getter方法,還有一個包含這三個屬性的構造方法。如果用spring

Springbean注入方式

(http://glzaction.iteye.com/blog/1299441) Spring中依賴注入有三種注入方式: 一、構造器注入; 二、設值注入(setter方式注入); 三、Feild方式注入(註解方式注入)。 一、構造器注入      構造器

spring的五依賴注入方式

平常的java開發中,程式設計師在某個類中需要依賴其它類的方法,則通常是new一個依賴類再呼叫類例項的方法,這種開發存在的問題是new的類例項不好統一管理,spring提出了依賴注入的思想,即依賴類不由程式設計師例項化,而是通過spring容器幫我們new指定例項並且將例項注

Spring中IoC兩介面和兩依賴注入方式的比較

spring是一個開源框架,是為了解決企業應用程式開發的複雜性而建立的,為J2EE應用程式開發提供整合的框架。簡單來說,spring是一個輕量級的控制反轉IOC和麵向切面AOP的容器框架。spring框架會對定義在配置檔案中的bean例項自動管理,這個bean也就是Java

Spring框架入門(一)簡介及基本注入方式例項

目錄 1介面注入 2設值注入 配置:導包 配置檔案: 測試類: 配置檔案: Test: 一、基本含義 Spring框架主要降低程式的耦合性,耦合性的意思為實現介面和實現類之間的關聯性,S

Spring通過全類名(反射)配置Bean以及依賴注入

配置Bean其實就是使用DI依賴注入,將Bean交給IOC容器管理,實現IOC控制反轉,達到解耦的過程。 Spring通過全類名(反射)配置Bean特點: 1. 基於xml檔案的方式, 2. 通過全類名反射, 3. 依靠IOC容器, 4. 依賴注入的方式

SSM框架之Spring-IoC和DI的理解與常用注入方式

SSM 框架學習 (Spring篇) 一、IoC和DI IoC(Inversion of Control)控制反轉Spring兩大核心之一,是一種不同於傳統的設計思想。 那何來控制反轉一說呢?我們先看傳統的Java程式設計,當我們一個類內部需要一個物

Spring的四依賴注入方式例項

// 第三種方式,靜態工廠方式,在工廠類中返回靜態IOCFactory物件 public void setIOCdependency(IOCdependency iocdenpendency) { this.IOCdependency = iocdenpendency; }與上面兩個方法不同,這次在配置檔案中

Spring筆記之七(Types of Injection) Spring依賴注入實現型別

本文研究Spring的三種依賴注入實現型別——介面注入(Interface Injection)、設值注入(Setter Injection)、構造子注入(Constructor Injection)。 Type1 介面注入: 傳統的建立介面物件的方法, 藉助介面來將呼叫者與

Spring的兩依賴注入方式:setter方法注入與構造方法注入

   Spring的兩種依賴注入方式:setter注入與構造方法注入,這兩種方法的不同主要就是在xml檔案下對應使用property和constructor-arg屬性, 例如: property屬

angular的幾依賴注入方式

1、useClass 提供器的一種寫法是這樣的 providers: [...Service...], 其完全寫法為 providers: [{provide:Service,useClass:Service}], provide提供token而實際使用的服

基於xml的兩依賴注入方式(建構函式注入,setter注入

概述 Spring中依賴注入dependency injection(DI)一般來說有兩種形式: 1)基於xml的依賴注入, 2)基於註解的依賴注入。 基於xml的依賴注入方式通常又可以分為:1)建構函式方式注入。2)setter方式注入。 環境 Spring4.3.9