Spring概念及IOC使用
Spring概述
1. Spring概念
Spring是分层的JavaSE/EE应用full-stack轻量级开源框架,以IOC(inverse Of Control,反转控制)和AOP(Aspect Oriented Programming,面向切面编程)为内核,提供了展示层SrpingMVC和持久层SpringJDBC以及业务层事务管理等众多企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,主键成为使用最多的JavaEE企业级应用开发框架。
2017 年 9 月份发布了 spring 的最新版本 spring 5.0 通用版(GA)

2. Spring的优势
- 方便解耦,简化开发
通过Spring提供的IOC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过程程序耦合。用户也不必再为单例模式类、属性文件解析等浙西很底层的需求编写代码,从而更专注于上层的应用。
- AOP编程的支持
通过Spring的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应对。
- 声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事物的管理,提高开发的效率和质量。
- 方便程序的测试
可以用非容器依赖的编程方式进行所有测试工作,测试不再是昂贵的操作,而是随手可 做的事情。
- 方便集成各种优秀框架
Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz 等)的直接支持。
- 降低 JavaEE API 的使用难度
Spring 对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的 使用难度大为降低。
- Java 源码是经典学习范例
Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以 及对 Java 技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。
3. Spring体系结构

Core Container:对象容器
Beans,Core,Context,SpEL:Map对象,可以通过解耦的方式获取对象。
IOC产生背景
1. 程序耦合:程序之间存在依赖关系
包括:类之间的耦合
方法间的耦合
三层架构实现的项目,耦合性太高。
程序解耦:降低程序间的依赖关系
开发中做到:编译期不依赖,运行时才依赖。
类之间解耦思路:
-
- 通过反射创建对象,而避免使用new关键字
- 通过读取配置文件中的全限定类名,来获取要创建对象的类名
2. IOC解决程序耦合
IOC(Inversion of Control, 控制反转)把自主创建对象(new对象)的权利交由框架或工厂,框架通过注入的依赖进行依赖查找,通过非面向对象编程的方式实现对象的创建,减少程序的耦合。
使用步骤:
- 创建容器配置文件。
<?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.xsd"> <bean id="AccountService" class="com.spring.two.service.AccountServiceImpl"></bean> <bean id="AccountDao" class="com.spring.two.dao.AccountDaoImpl"></bean> </beans> - 通过ApplicationContext获取对象
public class IOCTest { public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml"); Account account=new Account(); AccountService service=context.getBean("AccountService", AccountService.class); service.saveAccount(account); } }
IOC细节
1. IOC相关类的继承结构

2. ApplicationContext容器接口
实现了BeanFactory、ResourceLoader等接口。
ApplicationContext的实现类:通过配置内容创建容器。
ClassPathXmlApplicationContext: 加载类路径下的配置文件,创建容器;
FileSystemXmlApplicationContext: 加载磁盘路径下的配置文件,创建容器;
AnnotationConfigApplicationContext: 读取注解,创建容器;
ApplicationContext接口 VS BeanFactory接口:
ApplicationContext:适用于单例对象
立即加载(默认):读取完配置文件后,创建配置文件中的所有对象。对象被调用时,返回已创的对象。
可以通过配置文件,改变对象的创建模式(单例,多例)。
BeanFactory:适用于多例对象
延迟加载:当对象d被需要时,通过配置文件,创建对象。
3. <bean>标签:用于容器创建对象
在xml中配置类标识和全限定类名的关系,ApplicationContext容器通过加载<bean>标签,以非OOP的方式创建对象。
属性:
id:对象在容器中的唯一标识。
class:对象的全限定类名
scope:对象的作用范围。
init-method:初始化方法名
destroy-method:销毁方法名
子标签:
<constructor-age>:通过构造方法,注入依赖
<property>:通过set方法,注入依赖
scope属性:容器对象的作用范围。
a)singleton:默认的,创建单例对象。
生命周期:
出生:立即加载。容器一旦加载配置文件,对象就随之创建;
存活:只要容器存活,对象就存活;
死亡:容器销毁,对象也死亡。
b) prototype: 创建多例对象。
生命周期:
出生:对象被使用时,由Spring框架创建;
存活:对象使用过程中一直存活;
死亡:对象长时间不使用并没有别的对象引用时,由垃圾的回收期回收。
c)request: 作用于web应用的一次请求范围,将对象存储到request域中
d)session:作用于web应用的一次会话范围,将对象存储在session域中。
e)global-session:作用于集群环境的会话范围。
集群环境:同一IP的所有服务器中,一次会话中共享数据。

通过bean标签创建对象的三种方式:
a) <bean id=””, class=””>: 使用类的默认构造函数创建对象,并存入Spring容器。
如果类中没有默认构造函数,则对象无法创建
b) <bean id=””, class=”全限定类名”, factory-method=”方法”>:使用工厂的方法创建对象(某个类的方法创建对象,并存入core contrainer)
c) <bean id=””, class=”全限定类名”, factory-mehtod=”方法”>: 使用工厂的静态方法创建对象(某个类的静态方法创建对象,并存入spring容器)
4. 注入依赖
Spring通过IOC以非OOP的方式创建对象,降低程序间的耦合。
并且Spring维护类之间的依赖关系,即当类需要使用其他类的对象时,由Spring提供所依赖的对象,我们只需要在配置文件中说明依赖的关系,这就称为依赖注入。
依赖注入的类型:
- 基本类型和String:String会转成需要的基本类型
- Bean类型(在配置文件中或注解中配置过的Bean类)
- 复杂类型:数组、List、Set、Map、Properties等
依赖注入的方式:
- 构造函数+<constructor-org>子标签
- 在类中,依赖通过类构造函数的参数赋值。
- 在配置文件中,通过<constructor-org>标签注入依赖:
属性:type: 注入数据的类型
index:注入数据的索引
name: 注入数据的参数名
value:要注入的基本类型或String类型的数据。
ref:要注入的bean对象。包括注解配置的或xml配置的bean对象
构造函数方法注入:
<bean id="AccountService2" class="com.spring.two.service.AccountServiceImpl2">
<constructor-arg name="name" value="neo"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="birthday"></constructor-arg>
</bean>
<bean id="birthday" class="java.util.Date"></bean>
构造函数:
public AccountServiceImpl2(String name, int age, Date birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
优点:Spring创建bean对象时,依赖都被注入,否则无法创建成功
缺点:改变了bean对象实例化的方式,所需依赖必须注入,即使是用不到时
2.set方法+<property>标签
-
- 在类中,依赖通过setXXX方法赋值
- 配置文件中,通过<property>标签注入依赖:
属性:
name: 注入数据的set方法名
value:注入的基本类型或String类型数据
ref:注入的bean类型数据。
<!-- set方法注入-->
<bean id="AccountService2" class="com.spring.two.service.AccountServiceImpl2">
<property name="name" value="neo"></property>
<property name="age" value="17"></property>
<property name="birthday" ref="birthday"></property>
</bean>
<bean id="birthday" class="java.util.Date"></bean>
优点:创建对象时,没有明确的依赖限制,直接使用默认构造函数创建;
缺点:如果对象的某个依赖必须存在,通过set方式无法满足此要求。

浙公网安备 33010602011771号