依赖注入(DI)与控制反转(IoC)的概念,以及实现方式

IoC的概念

IoC的概念:在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。这样控制权就由应用代码转移到了Spring容器,控制权发生了反转,即为控制反转。

Ps:我在初次看到这个定义时,反复读了很多遍没办法理解定义所描述的概念,在通过入门程序之后,有所体会,大概的含义就是,在原来的实际编程中,创建类,并给它赋予各种属性和方法,在调用类方法时,多数情况是先生成一个类对象,比如:

User  user = new  User;
user.say()

这种方式是我手动的创建了类的对象,也可以说是类的实例,实例的创建是由我所写的new方法创建出来的。而在入门程序中,我并没有使用new方法,而是在Spring文件里配置了类的属性,在需要使用类方法的时候,通过Spring容器来直接获取类的实例:

UserDao userDao=(UserDao)applicationContext.getBean("userDao");
		userDao.say();

这种实例方式的转换,就是控制反转,用户不再自己实例化对象,交给Spring框架完成这个过程。

DI的概念

DI的概念:从Spring的角度去看,Spring容器负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入。
Ps:其实DI和IoC是同一个概念在不同角度上去阐述的,IoC的概念阐述是站在调用者的角度去阐述的,DI的概念是站在Spring容器的角度去阐述的,在使用Spring容器进行实例化的时候,我们创建了一个变量,如上面所写的userDao我们使用这个变量来接受了Spring容器为我们实例化的对象,这个过程就是定义里所说的Spring容器负责将被依赖对象赋值给调用者的成员变量,实际描述的就是Spring容器为我们实例化对象的过程。

具体实现方式

首先在入门程序的基础上,新定义一个接口命名为UserService,在其中定义一个say()方法。

再定义一个实现类,命名为UserServiceImpl,在其中实现say()方法:

public class UserServiceImpl implements UserService {

	@Override
	public void say() {

		System.out.println("userService say Hello World!");

	}

}

如果这样写的话只是单纯利用了Spring容器的实例化功能,如果在执行userService的同时想要调用入门程序中userDao的方法,就要在实现类中定义一个userDao属性用于实现依赖,然而此时定义的userDao属性是空的,Spring无法提供给我们一个UserDao对象,所以我们需要为userDao属性添加一个set方法用于实现依赖注入,修改后的代码如下:

package beginner.ioc;

public class UserServiceImpl implements UserService {

	private UserDao userDao;

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void say() {

		this.userDao.say();

		System.out.println("userService say Hello World!");

	}

}

(我在编写实现类的时候出现了一个小错误,错误信息是:The method say() of type UserServiceImpl must override or implement a supertype method。错误原因:是由于写完接口没有保存,直接写实现类导致。不是什么大问题,但是是编写习惯导致的,以后要注意。)

在Spring的配置文件,也就是入门程序中的ApplicationContext.xml中,新加入一个bean元素,将其id属性值设为userService,class属性值设为实现类的全限定名。定义一个property属性将其name属性设置为userDao,设置一个ref属性用于引用入门程序中编写的userDao对象,将其值设置为userDao。(虽然两个属性值都为userDao,但是其含义是不同的,name属性的userDao是我在UserServiceImpl类里定义的userDao属性,而ref属性的userDao是在Spring容器中配置文件所设置的UserDao类的id值,也就是说如果我在UserServiceImpl中定义的UserDao类型的属性命名为userDao1,在配置文件中定义的UserDao类的id值设置为userDao2,那么property的name属性应该设值为userDao1,ref属性应该设值为userDao2。)

编写好的配置文件代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">


	<bean id="userDao" class="beginner.ioc.UserDaoImpl"></bean>

	<bean id="userService" class="beginner.ioc.UserServiceImpl">

		<property name="userDao" ref="userDao">
		</property>

	</bean>
</beans>

最后编写测试类代码:

package beginner.ioc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestDI {

	public static void main(String[] args) {
		//1.初始化Spring容器,加载配置文件
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
		//2.通过容器获取UserService实例
		UserService userService = (UserService) applicationContext.getBean("userService");
		//3,调用实例中的say();方法
		userService.say();
	}
}

成功运行:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值