从头认识Spring-1.1 什么是依赖注入?为什么需要依赖注入?

这一章节我们来讨论一下什么是依赖注入?为什么需要依赖注入?

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


  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值