Spring的概述
Spring是什么
Spring是分层的Java SE/EE应用 full-stack
轻量级开源框架,以IoC(Inverse Of Control:反转控制)
和AOP(Aspect Oriented Programming:面向切面编程)
为内核,提供展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库。
程序耦合以及解耦
- 程序的耦合
- 耦合: 程序间的依赖关系
- 包括:
- 类之间的依赖
- 方法间的依赖
- 解耦: 降低程序间的依赖关系
- 实际开发中:
- 应该做到编译期不依赖,运行时才依赖
- 解耦思路:
- 使用反射来创建对象,而避免用new
- 通过读取配置文件来获取要创建对象的全限定类名
用工厂模式创建对象(解耦)
1 | /** |
有了这样的工厂就可以通过AccountService service = (AccountService) BeanFactory.getBean("accountService");
方式来创建对象,就是将创建对象的控制权交给了工厂,这就是控制反转
通过这种方式降低了程序之间的耦合
IOC的概念和Spring中的IOC
控制反转(IOC)把对象创建的权利交给了框架,是框架的重要特征,它包括了依赖注入(DI)和依赖查找(Dependency Lookup)。其主要作用就是削减计算机程序的耦合(程序间的依赖关系)
Spring中基于XML的IOC环境搭建
在pom.xml的依赖中加入
1
2
3
4
5<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>然后在resources中创建一个bean.xml文件并导入约束
1
2
3
4
5
6<?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">
</beans>把对象的创建交给Spring来管理
1
2<bean id="accountService" class="com.xushui.service.Impl.AccountServiceImpl"></bean>
<bean id="accountDao" class="com.xushui.dao.Impl.AccountDaoImpl"></bean>
4.测试代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
* 获取spring的IOC核心容器,并根据id获取对象
* @param args
*/
public static void main(String[] args) {
// 1.获取核心容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
// 2.根据id获取bean对象
AccountService accountService = (AccountService) ac.getBean("accountService");
// 两种方式都可以,一种是强制转换,一种是加上你要转的类的字节码文件
AccountDao accountDao = ac.getBean("accountDao",AccountDao.class);
System.out.println(accountService);
System.out.println(accountDao);
}
一些要注意的地方
ApplicationContext的三个常用实现类
1. ClassPathXmlApplicationContext: 它可以加载类路径下的配置文件,要求配置文件必须在类路径下(常用)
2. FileSystemXmlApplicationContext: 它可以加载磁盘任意路径下的配置文件(必须有访问权限)
3. AnnotationConfigApplicationContext: 它是用于读取注解创建容器的
核心容器的两个接口引发的问题
ApplicationContext(大多数采用这个): 单例对象适用
它在构建核心容器时,创建对象采取的策略是立即加载的方式(一读取完配置文件马上创建配置文件中配置的对象)
Spring是个很智能的框架,当你选择作用范围为prototype时,它会自动变为延迟加载策略
BeanFactory: 多例对象适用
它在构建核心容器时,采用的是延迟加载的策略(什么时候根据id获取对象了,什么时候才创建对象)
Spring对bean管理的细节
创建bean的三种方式
- 使用默认构造函数创建,若类中没有默认构造方法,则对象无法创建
1 | <bean id="accountService" class="com.xushui.service.Impl.AccountServiceImpl"></bean> |
- 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
1 | <bean id="instanceFactory" class="com.xushui.factory.InstanceFactory"></bean> |
- 使用工厂中的静态方法创建对象(使用某个类的静态方法创建对象,并存入spring容器)
1 | <bean id="accountService" class="com.xushui.factory.StaticFactory" factory-method="getAccountService"></bean> |
bean对象的作用范围
bean作用范围调整
- bean标签的scope属性:
- 作用:用于指定bean的作用范围
- 取值: 前两个比较常用
singleton
: 单例的(默认值)prototype
: 多例的request
: 作用于web项目的请求范围session
: 作用于web项目的会话范围global-session
: 作用于集群环境的会话范围(全局会话范围),当不是集群环境时,他就是session
bean对象的生命周期
- 单例对象
- 出生: 当容器创建时,对象出生
- 活着: 只要容器还在,对象一直活着
- 死亡: 容器销毁,对象死亡
总结
: 单例对象的生命周期和容器相同
- 多例对象
- 出生: 当我们使用对象时,Spring框架为我们创建
- 活着: 对象只要是在使用过程中。一直是活着
- 死亡: 当对象长时间没用,且没有别的对象引用,由Java的垃圾回收机制回收
依赖注入(Dependency Injection)
- 依赖关系的管理:
- 都交由Spring框架来维护
- 当前类需要其他类的对象,由Spring提供,我们只用在配置文件中说明
- 依赖关系的维护我们就称之为依赖注入
注意:
经常变化的数据,并不适合注入方式
支持注入的数据类型
- 基本类型和String
- 其他bean类型(配置文件中或者注解配置过的bean)
- 复杂类型/集合类型
注入类型
- 使用构造函数提供
- 使用set方法提供
- 使用注解提供
构造函数的注入
- 使用的标签: constructior-arg
- 标签出现的位置: bean标签的内部
- 标签中的属性
type
: 用于指定要注入的数据的数据类型,该数据赋值给构造函数中该数据类型的一个或多个index
: 用于给构造函数中指定索引位置的参数赋值 索引从0
开始name
: (常用)用于给构造函数中指定名字的参数赋值value
: 用于提供String类型和基本类型的数据ref
: 用于指定其他bean类的数据,值得就是Spring的IOC核心容器中出现过的bean对象
示例
1 | public class AccountServiceImpl implements AccountService { |
bin.xml中
1 | <bean id="accountService" class="com.xushui.service.Impl.AccountServiceImpl"> |
优势:
在获取bean对象时,注入数据是必须的操作,否则对象无法创建。
弊端:
改变了bean的实例化方式,即使我们在创建对象时,用不到这些数据,也必须提供
set方法注入(常用)
- 使用的标签: property
- 出现的位置: bean标签的内部
- 标签属性:
- name:用于指定注入时所调用set的方法的名称
- value和ref与构造函数注入一样
优势:
创建对象是没有明确的限制,可以直接使用默认的构造函数
弊端:
如果有某个成员必须有值,set方法无法保证
复杂类型/集合类型注入
1 | <bean id="accountService3" class="com.xushui.service.Impl.AccountServiceImpl3"> |
- 用于给List结构集合注入标签:
list
、array
、set
- 用于给Map结构集合注入标签:
map
、props
- 结构相同标签可以互换