这一章节我们来讨论一下什么是依赖注入?为什么需要依赖注入?
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();
}
}
为了测试方便,我们增加了一个测试类。
(1)通过配置不同的歌曲,从而实现歌唱家能够唱不同的歌曲,不像之前的代码那样,只能够唱同一首歌
(2)通过配置,可以重复利用相同的类,来灵活配置不同的歌唱家唱不同的歌曲(如下面的配置)。
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