1. 程式人生 > >從頭認識Spring-1.1 什麽是依賴註入?為什麽須要依賴註入?

從頭認識Spring-1.1 什麽是依賴註入?為什麽須要依賴註入?

hub unit 註意 pac stat xmlns mave imp cati

這一章節我們來討論一下什麽是依賴註入?為什麽須要依賴註入?

1.什麽是依賴註入?

筆者理解的是:對象的生成不再是通過顯示的new,並且到spring容器裏面取。對象的創建是使用註入這樣的形式


2.為什麽須要依賴註入?

(1)解耦

(2)易於測試


我們以歌唱家唱歌這個為樣例,在沒有使用依賴註入情況下的代碼:

package com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1;

public class Song {
	@Override
	public String toString() {
		return "a song";
	}
}



package com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1;

public class Singer {
	private Song song = null;

	public Singer() {
		song = new Song();//強耦合的地方
	}

	public void singTheSong() {
		System.out.println(song.toString());
	}

	public static void main(String[] args) {
		new Singer().singTheSong();
	}
}


輸出:

a song


上面的代碼耦合緊密。會出現兩個問題:

(1)須要測試Singer的時候,必須new一個song出來

(2)Singer僅僅能是唱指定的song,假設換一首。就必須又一次改動代碼。


我們換成依賴註入形式:

(註意,因為代碼比較多,並且我是使用maven形式構建項目,因此。詳細的代碼能夠到我的github去查看,本文最底部有我的github地址)

package com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1;

public class Song {

	private String name;

	public Song(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "the song:" + name;
	}
}

歌曲類我們添加了歌曲的名字,這樣能夠通過依賴註入變化不同的曲目,使得歌曲類更加靈活


package com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1;

public class Singer {
	private Song song = null;

	public Singer(Song song) {
		this.song = song;
	}

	public void singTheSong() {
		System.out.println(song.toString());
	}
}


歌唱家的類不變。


package com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:ApplicationContext-test.xml" })
public class SingerTest {
	@Autowired
	private ApplicationContext applicationContext;

	@Test
	public void testSinger() {
		Singer singer = applicationContext.getBean(Singer.class);
		singer.singTheSong();
	}

}


為了測試方便,我們添加了一個測試類。


<?

xml version="1.0" encoding="UTF-8"?

> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="song1" class="com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1.Song"> <constructor-arg value="my heart will go on" /> </bean> <bean id="singer" class="com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1.Singer"> <constructor-arg ref="song1" /> </bean> <bean id="song2" class="com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1.Song"> <constructor-arg value="there will be" /> </bean> </beans>


我們重點來說一下上面的配置文件。因為靈活性的實現就體如今上面了

(1)通過配置不同的歌曲,從而實現歌唱家能夠唱不同的歌曲,不像之前的代碼那樣。僅僅能夠唱同一首歌

(2)通過配置。能夠反復利用同樣的類,來靈活配置不同的歌唱家唱不同的歌曲(如以下的配置)。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
	<bean id="jack"
		class="com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1.Singer">
		<constructor-arg ref="song1" />
	</bean>
	<bean id="song1"
		class="com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1.Song">
		<constructor-arg value="my heart will go on" />
	</bean>
	<bean id="rose"
		class="com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1.Singer">
		<constructor-arg ref="song2" />
	</bean>
	<bean id="song2"
		class="com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1.Song">
		<constructor-arg value="there will be" />
	</bean>

</beans>

然後我們僅僅要略微改動一下測試類,而前面的歌唱家和歌曲類不需改動

package com.raylee.my_new_spring.my_new_spring.ch01.topic_1_1;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:ApplicationContext-test.xml" })
public class SingerTest {
	@Autowired
	private ApplicationContext applicationContext;

	@Test
	public void testJackSinger() {
		Singer singer = (Singer) applicationContext.getBean("jack");
		singer.singTheSong();
	}

	@Test
	public void testRoseSinger() {
		Singer singer = (Singer) applicationContext.getBean("rose");
		singer.singTheSong();
	}

}

我們就可以配置出不同的歌唱家唱不同的歌曲。

輸出:

the song:my heart will go on

或者

the song:there will be


3.依賴註入的優缺點:

長處:

(1)對象的定義放在xml裏面。我們能夠靈活的配置

(2)易於測試

(3)易於裝卸

缺點:

(1)創建對象的流程麻煩了

(2)因為spring大部分採用反射機制來實現。因此性能一定是個問題

(3)因為對象的定義放在xml。對於使用eclipse來重構就會比較麻煩


總結:這一章節我們主要介紹了什麽是依賴註入?為什麽須要依賴註入?


我的github:https://github.com/raylee2015/my_new_spring


從頭認識Spring-1.1 什麽是依賴註入?為什麽須要依賴註入?