Spring简介和IOC容器使用
Spring简介
介绍
- spring是一个开源框架,使用Spring开发可以将Bean对象交给Spring容器来管理,使得很多复杂的代码在Spring开发中会变的简洁,有效的降低代码耦合度,极大的方便后期的维护、升级、拓展。
四种关键策略
- 基于 POJO 的轻量级和最小侵入性编程
- 通过依赖注入和面向接口实现松耦合
- 基于切面和惯例进行声明式编程
- 通过切面和模板减少样板式代码
特点
- 非侵入式:基于 Spring 开发的应用中的对象可以不依赖于 Spring 的 API。
- 容器:Spring 是一个容器,因为它包含并且管理应用对象的生命周期。
- 控制反转:IOC (Inversion of Control),指的是将对象的创建权交给 Spring 去创建。
- 使用 Spring 之前,对象的创建都是由我们自己在代码中 new 创建。而使用 Spring 之后。对象的创建都是由给了 Spring 框架
- 依赖注入:DI (Dependency Injection),是指依赖的对象不需要手动调用 setXX 方法去设置,而是通过配置赋值。
- 面向切面编程:Aspect Oriented Programming——AOP。
- 组件化:Spring 实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用 XML 和 Java 注解组合这些对象。
- 一站式:在 IOC 和 AOP 的基础上可以整合各种企业应用的开源框架和优秀的第三方类库。
jar包下载
https://repo.spring.io/simple/libs-release-local/org/springframework/spring/
- -dist 后缀表示该文件夹下存放的是 jar 包,文档和 xsd 文件;
- -docs 后缀表示该文件夹下存放相关文档,开发指南和 API;
- -schema 里存放了 Spring 所用的 xsd 文件。
Spring IOC容器
IOC思想
IOC (Inversion of Control) 是指在程序开发中,对象实例的创建不再由调用者管理,而是由 Spring 容器创建。Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转。简单说就说Spring会完成对象创建,并将对象放入容器中
容器概念
IOC 容器就是具有依赖注入功能的容器,IOC 容器负责实例化、定位、配置应用程序中 的对象及建立这些对象间的依赖。应用程序无需直接在代码中 new 相关的对象,应用程序 由 IOC 容器进行组装。在 Spring 中 BeanFactory 是 IOC 容器的实际代表者。
Bean概念
在 Spring 中,被 Spring 容器所管理的对象称之为”Bean”对象。一个 Spring 的 Bean 对象可以是任何形式的 POJO。任何class类都可以视力恶化,并且class不用实现任何接口
容器类型
- BeanFactory是基础类型的IOc容器,实例化对象和管理生命周期
- ApplicationContext是BeanFactory的子接口,功能更强大
ApplicationContext有两个实现类
- ClassPathXmlApplicationContext
该类从类路径 ClassPath 中寻找指定的 XML 配置文件,找到并装载完成 ApplicationContext 的实例化工作 - SystemXmlApplicationContext
该类从指定的文件系统路径中寻找指定的 XML 配置文件,找到并装载完成 ApplicationContext 的实例化工作
两者区别
:在读取 Spring 的配置文件时,
FileSystemXmlApplicationContext 不再从类路径中读取配置文件,而是通过参数指定配置文 件的位置,它可以获取类路径之外的资源,如“F:/workspaces/applicationContext.xml”;
IOC容器使用
- 需要导入相应jar包
- 导入jar包之后需要相应的Spring配置文件,用于管理相应bean对象
- 创建对应的接口和实现类,并通过修改配置文件,来管理其相应的对象
- 通过启动IOC容器来获取相应.class的对象
jar包添加
Core Container(核心容器)
Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上 下文模块和 Expression Language 表达式语言模块组成,具体介绍如下。
- Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称 为 Bean。
- Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
- Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
- Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。是对JSP2.1 规范中规定的统一表达式语言(Unified EL)的扩展。
以及Core需要依赖的日志包
添加Spring配置文件
文件名随意取,一般起名:applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd" >
<bean id="usersService" class="com.bjsxt.service.impl.UsersServiceImpl"/>
</beans>
创建接口和实现类
public interface UsersService {
void addUsers();
}
public class UsersServiceImpl implements UsersService { @Override
public void addUsers() {
System.out.println("UsersService addUsers ......");
}
}
获取IOC容器中的对象
public class UsersServiceTest {
public static void main(String[] args) {
/* UsersService usersService = new UsersServiceImpl(); usersService.addUsers();*/
//启动 Spring IOC 容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//从 IOC 容器中获取 UsersService usersService = (UsersService) applicationContext.getBean("usersService"); usersService.addUsers();
}
这样我们就可以完成了对usersService对象的获取,我们使用IOC容器获取,而不是通过new的方式。
IOC容器创建Bean的三种方式
- 通过构造方法
实例化对象时,和正常new的时候一样,new的时候调用构造方法,从而完成实例化的过程
public class UsersServiceImpl implements UsersService { public UsersServiceImpl(){ System.out.println("Init.......");
}
@Override
public void addUsers() {
System.out.println("UsersService addUsers ......");
}
}
- 通过静态工厂方法创建对象
静态工厂的话不需要频繁的创建对象
public class ObjectFactory {
public static UsersService getInstance(){
return new UsersServiceImpl();
}
}
<!-- 通过静态工厂方法实例化对象,加了factory-method不会实例化这个类ObjectFactory,而是根据你这个类的方法去实例化对象,创建出来之后会把对象放在IOC容器中-->
<bean id="UsersService2" class="com.hhxx.factory.ObjectFactory" factory-method="getInstance"/>
- 通过动态工厂方法创建对象
由于是动态的,因此需要先实例化clsss,再由该对象调用其方法
public class DynamicObjectFactory {
public UsersService getInstance(){
return new UsersServiceImpl();
}
}
<!--通过动态工厂方法,实例化对象-->
<!-- 先实例化DynamicObjectFactory,在通过第二个bean标签 factory-bean下的getInstance方法,并将对象存放容器中
和usersService3 唯一标识形成绑定 这样只需要获取这个id就能调取到相应对象-->
<bean id="dynamicObjectFactory" class="com.hhxx.factory.DynamicObjectFactory"/>
<bean id="usersService3" factory-bean="dynamicObjectFactory" factory-method="getInstance"/>
SpringIOC容器获取Bean对象方式
- 通过id或name获取Bean对象
applicationContext.getBean(id|name);
name不能重复但是可以有多个
配置文件
<bean id="usersService" name="name1,name2,name3" class="com.bjsxt.service.impl.UsersServicesImpl" />
- 通过类型获取Bean对象
IOC容器中同一个类型的对象只能只有一个不能有多个,类型必须唯一的
applicationContext.getBean(Class clazz);
UsersService usersService = applicationContext.getBean(UsersServiceImpl.class); usersService.addUsers();
- 通过idhuoname与类型获取bean对象
在 SpringIOC 容器中,通过类型获取对象时,如果同一类型存在多个对象,我们可以使用添加id 或 name 来识别需要获取的对象
方式1:
UsersService usersService = applicationContext.getBean("name1",UsersServiceImpl.class);
usersService.addUsers();
方式2
先获取到容器中所有的bean对象id,通过getBeanDefinitionNames()方法,返回所有bean对象id数组而不是name,通过索引来获得相应的具体对象
//获取 Spring IOC 容器中所有的 Bean 对象的 ID
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for(String name: beanDefinitionNames){ System.out.println(name);
}
UsersService usersService = applicationContext.getBean(beanDefinitionNames[0],UsersServiceImp l.class);
usersService.addUsers();
IOC容器创建对象的策略
Spring IOC 容器在启动时默认的会将在配置文件中所配置的所有 Bean 对象立即进行实 例化,并保存在IOC容器中。我们可以通过
需要注意的是lazy init="false"scope作用域为singleton(单例,也是默认属性值)有效
容器创建对象可以分为:
- 立即创建即默认的,在容器启动时会实例化文件中的所有bean对象
- 延迟创建 lazy-int=“true” 在调用getbean方法时进行创建
Bean对象的作用域
作用域限定了 Spring Bean 的作用范围,在 Spring 配置文件定义 Bean 时,通过 声明 scope 配置项,可以灵活定义 Bean 的作用范围。
singleton(单例)
singleton 为 scope 属性的默认值。当 scope 属性的值为 singleton 时,Spring IOC 容器启 动时会立即实例化一次 Bean 对象,并一直被 Spring IOC 容器所缓存,所以生命周期较长。
- singleton 特点:
Spring IOC 容器启动时会创建 Bean 对象 也就是构造方法会调用
每次调用 getBean 都返回 spring 容器中的唯一一个对象
<bean id="usersService" name="name1,name2,name3" class="com.bjsxt.service.impl.UsersServicesImpl" scope="singleton" />
prototype(多例)
lazy-init失效,是在getbean的时候进行实例化
当 scope 属性的值为 prototype 时,每次调用调用 getBean 方法时都会返回一个新的 Bean 对象,Spring IOC 容器并不会缓存该对象,所以就不再负责管理它的生命周期。
- prototype 特点:
Spring IOC 容器启动时不会创建 Bean 对象。
每次调用 getBean 都会创建一个新 Bean 对象。
<bean id="usersService" name="name1,name2,name3" class="com.bjsxt.service.impl.UsersServicesImpl" scope="prototype"/>
单例和多例,底层其实对应的就是静态工厂和动态工厂