一.SpringIOC的简单概述
1.1 什么是IOC?
IOC全称Inversion Of Control,意为控制反转,它包括依赖注入和依赖查找。那么何为控制反转呢?对比传统的创建对象的方式,我们往往会使用new关键去创建对象,是类主动的去实例化自己。但是在spring中我们将创建对象的权力交给了了sping容器,类不在具有创建对象的权力,这种创建对象权力的转移,我们称之为“控制反转”。
1.2 为什么要使用IOC?
我们知道在我们设计软件时应当遵守"高内聚低耦合"的设计原则,也就是我们要尽量去降低我们模块之前的依赖性。而过度使用new关键字会导致程序的依赖程度大大提高,不符合我们软件开发的思想,也不利于团队协作开发。而在spring中, 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化Bean 并建立 Bean 之间的依赖关系, 大大降低了我们程序模块的依赖关系。
1.3 springIOC原理概述
spring启动时,读取应用程序提供的Bean配置信息,并在spring中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖关系,为上层应用提供准备就绪的运行环境,其中Bean的缓存池用HashMap实现。其实现原理就是工厂模式加反射机制。
1.4 依赖注入
在依赖注入中您不必创建对象,但必须描述如何创建它们。 您不是直接在代码中将组建和服务器连接在一起,而是描述配置文件中那些组建需要那些服务。由IOC容器将它们装配到一起。通常依赖注入可以通过3种方式完成,构造函数注入,setter注入,接口注入,在spring framework中,仅使用构造函数和setter注入。
构造函数注入 | setter注入 |
---|---|
没有部分注入 | 有部分注入 |
不会覆盖setter属性 | 会覆盖setter属性 |
任意修改都会创建一个新实例 | 任意修改都不会创建一个新实例 |
适用于设置很多属性 | 适用于设置少量属性 |
二.SpringIOC举例
我们以学生选课系统中学生查询可选课信息为例,当表现层点击查询你可选课程时,表现层调用业务层,业务层调用持久层。
/*
持久层dao编写,这里dao模拟查询可选课程信息.首先编写持久层接口,然后是持久层接口的实现类.课程的实体类为Course.
*/
public interface CourseDao{
/*
查询所有课程
*/
List<Course> findAll();
/*
根据课程号查询相应的课程信息
*/
Course findByCid(int cid);
}
/*
dao层实现类
*/
public class CourseDaoImpl implements CourseDao{
/*
查询所有课程
*/
public List<Course> findAll(){
Syetem.out.println("dao层查询所有课程");
}
/*
根据课程号查询相应的课程信息
*/
public Course findByCid(int cid){
System.out.println("dao层根据cid查询了所有的课程"+cid);
}
}
/*
sercice层接口
*/
public interface CourseService{
/*
查询所有课程
*/
List<Course> findAll();
/*
根据课程号查询相应的课程信息
*/
Course findByCid(int cid);
}
/*
service层实现类
*/
public class CourseServiceImpl{
//持久层实体类,不要使用new关键字对其进行初始化,将其交由spring容器帮我们管理
CourseDao courseDao;
//提供set方法,便于使用xml文件注入数据
public void setCourseDao(CourseDao courseDao){
this.courseDao = courseDao;
}
public List<Course> findAll(){
//业务层调用持久层方法
List<Course> courses = courseDao.findAll();
}
public Course findByCid(int cid){
//业务层调用持久层方法
Course c = courseDao.findByCid(1);
}
}
使用配置文件Spring配置文件applicationContext.xml,将dao层和service层的类交给Spring管理。Spring配置文件主要包含类的信息,它描述了这些类是如何配置以及相互引入的。 但是xml文件冗长,如果没有正确的规划和编写,那么在大项目中管理变得非常困难。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--将业务层实体类交由spring管理-->
<bean id="业务层类名首字母改小写" class="业务层实体类的全类名">
<property name="accountDao" ref="accountDao" /> <!--注入数据-->
</bean>
<!--将持久层的实现类交由spring管理-->
<bean id="持久层类名首字母改小写" class="持久层实体类全类名">
<!--这里由于是模拟持久层,没有需要注入的数据-->
</bean>
</beans>
/*
模拟表现层
*/
public class Main{
public static void main(String[] args){
//1.获取spring核心容器
ApplicationContext ac = new ClassPathXmlApplicationContext("spring配置文件名字,这里将其配置在resources根目录下");
//2.通过核心容器获取业务层对象CourseService
CourseService cs = ac.getBean(CourseService.class);
//3.执行方法
cs.findAll();
}
}
2.1 两个常用的spring容器
BeanFactory和ApplicationContext是spring的两大核心接口,都可以当做spring容器。其中ApplicationContext是BeanFactoryd的子接口。BeanFactory使用懒加载,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。而ApplicationContext使用立即加载,它是在容器启动时,一次性创建了所有的Bean。。
以上是笔者参考了许多博文整理的关于SpringIOC的简单说明,如有错误还请批评指正。