Spring的依赖注入和控制反转(一)概念

Spring的依赖注入和控制反转——概念介绍

依赖注入

介绍控制反转之前需要介绍依赖注入,所谓依赖注入,就是把类中需要new的对象,改成类的属性,并且为该属性设置get、set方法,主程序如果需要调用类的话,要在主程序中set这个属性

也就是说,把类从new中解放出来,把初始化实例的工作交给调用它的程序

还是刚刚那个例子,NewDao不变,改变NewService类,将所需的newDao类改成自己的属性,并且为其设置get、set方法

public class NewsService {

//	NewsDao newsDao = new NewsDao();
	
	//=======这里是添加的内容
	private NewsDao newsDao;
	
	public NewsDao getNewsDao() {
		return newsDao;
	}

	public void setNewsDao(NewsDao newsDao) {
		this.newsDao = newsDao;
	}
	//=======这里是添加的内容
	
	public void save() {
		
		System.out.println("NewsService保存操作");
		newsDao.save();
		
	}

}

在主程序中这样测试:

public static void main(String[] args) {
		
//		NewsService newsService =new NewsService();
//		newsService.save();
		//======这是新的测试方法
		NewsService newsService =new NewsService();
		
		NewsDao newsDao = new NewsDao();
		newsService.setNewsDao(newsDao);
		newsService.save();
		
	}

这样的话,就把new一个newsDao的工作从newService转移给了测试类。

测试类所做的工作就叫做依赖注入,即把newService所需的实例,通过set方法注入给newService

控制反转

那么什么叫控制反转呢?

回顾一下,我们为了依赖注入做了什么工作呢

  1. 把newsDao改成newsService的私有属性,并且为其生成set和get方法
  2. 在测试类中为newsService使用set方法注入NewsDao的实例
  3. 使用newsService.save()方法

在使用依赖注入之前我们是怎么做的呢?

  1. 在NewsService中new一个newsDao
  2. 在NewsService里的save方法中使用newsDao
  3. 在测试类中直接使用newsService.save()方法

也就是其实我们只做了一件事,就是在测试方法中给newsService实例注入newsDao实例,其实就是做了依赖注入这件事

在用了依赖注入这个方法后,本来应该由NewsService实例化NewsDao,变成了由测试方法实例化NewsDao。也就是,本来应该由被调用者自己完成创建私有属性的工作,变成了由调用者创建被调用者所需的属性,这就叫控制反转

这样做的好处是什么呢?在面向接口编程的情况下,可以实现解耦

举个例子,现在有一个接口InterNews,它有一个save()方法

public interface InterNews{
	void save();
}

这个接口有两个实现类NewsDao1和NewsDao2

public class NewDao1 implement interNews{
	@Override
	public void save(){
		System.out.println("NewsDao1:第一种保存方式");
	}

}
public class NewDao2 implement interNews{
	@Override
	public void save(){
		System.out.println("NewsDao2:第一种保存方式");
	}

}

但是业务类并不关心到底是哪个实现类,总之我要调用传进来的实现类的save方法,因此我所使用的是InterNews接口进行编程。如果我们使用依赖注入的方法,那么NewsService类如下:

public class NewsService{
	private InterNews interNews;
	
	public InterNews getInterNews() {
		return interNews;
	}

	public void setInterNews(InterNews interNews) {
		this.interNews = interNews;
	}

	public void save(){
		//我不关心到底是InterNews的哪个是实现类,总之我要调用它的save方法
		interNews.save();	
	}

}

那么无论我要调用NewsDao1的save方法还是NewsDao2的方法都很轻易,只需要给newsService注入不同的实现类即可

public static void main(String[] args) {
	NewsService newsService = new NewsService();
	//调用第一种实现的save
	if(我想调用第一种实现){
        newsService.setInterNews(new NewsDao1);
        newsService.save();
	}
	if(我想调用第二种实现){
		//调用第二种实现的save
		newsService.setInterNews(new NewsDao1);
		newsService.save();
	}
}

但是如果我们不采用依赖注入那么NewsServcie和InterNews的实现类耦合度就很高

如果不采用依赖注入,如果我们想使用第一种实现:

public class NewsService{
	private InterNews interNews=new NewsDao1;

	public void save(){
		
		interNews.save();	
	}

}

这时候测试类很简单,并不需要依赖注入:

public static void main(String[] args) {
	NewsService newsService = new NewsService();
	newsService.save();	
}

但是如果我们想使用第二种实现的话,就得修改NewsService类的方法,将实例改成

public class NewsService{
	private InterNews interNews=new NewsDao2;

	public void save(){
		
		interNews.save();	
	}

}

可以看到,这样InterNews的是实现类和NewsService的实现类就明显增强了许多

下一节介绍Spring怎么实现依赖注入和控制反转

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值