SSM系列(一)---Spring IoC 分析
本文主要介绍了 Spring 框架,通过代码演示详细讲述了 Spring IoC 的具体流程。
更多文章欢迎访问我的个人博客–>幻境云图
1. 概述
Spring 是一个开源容器框架,可以接管 web 层,业务层,dao 层,持久层的组件,并且可以配置各种bean,和维护 bean 与 bean 之间的关系。其核心就是控制反转(IoC),和面向切面(AOP),简单的说就是一个分层的轻量级开源框架。
2. Spring 中的 IoC
IoC:(Inverse of Control )控制反转,容器主动将资源推送给它所管理的组件,组件所做的是选择一种合理的方式接受资源。
简单的理解:把创建对象和维护之间的关系的权利由程序中转移到Spring容器的配置文件中。
DI : (Dependency Injection) 依赖注入,IoC 的另一种表现方式,组件以一种预先定义好的方式来接受容器注入的资源。
3. IoC 例子
3.1 xml 配置文件方式
1. 准备 bean 对象
先准备两个简单的实体类 Student 和 Book,需要提供Getter/Setter 和有参数无参构造方法等。
Spring Bean是事物处理组件类和实体类(POJO)对象的总称,Spring Bean 被Spring IoC 容器初始化,装配和管理。
/**
* @author illusory
* @version 1.0.0
* @date 2019/4/18 0018
*/
public class Student {
private String name;
private int age;
private Book book;
//省略Getter/Setter和构造方法
}
/**
* @author illusory
* @version 1.0.0
* @date 2019/4/18
*/
public class Book {
private String type;
private String name;
//省略Getter/Setter和构造方法
}
2. 将 Bean 类添加到 Spring IoC 容器
将 Bean 类添加到 Spring IoC 容器有三种方式。
- 一种方式是基于XML的配置文件;
- 一种方式是基于注解的配置;
- 一种方式是基于 Java 的配置。
1. Spring Bean 类的配置项
Spring IoC 容器管理 Bean 时,需要了解 Bean 的类名、名称、依赖项、属性、生命周期及作用域等信息。为此,Spring IoC 提供了一系列配置项,用于 Bean 在 IoC 容器中的定义。
- ① class
该配置项是强制项,用于指定创建 Bean 实例的 Bean 类的路径。
- ② name
该配置项是强制项,用于指定 Bean 唯一的标识符,在基于 XML 的配置项中,可以使用 id和或 name 属性来指定 Bean 唯一标识符。
- ③ scope
该配置项是可选项,用于设定创建 Bean 对象的作用域。
- ④ constructor-arg
该配置项是可选项,用于指定通过构造函数注入依赖数据到 Bean。
- ⑤ properties
该配置项是可选项,用于指定通过 set 方法注入依赖数据到 Bean。
- ⑥ autowiring mode
该配置项是可选项,用于指定通过自动依赖方法注入依赖数据到 Bean。
- ⑦ lazy-initialization mode
该配置项是可选项,用于指定 IoC 容器延迟创建 Bean,在用户请求时创建 Bean,而不要在启动时就创建 Bean。
- ⑧ initialization
该配置项是可选项,用于指定 IoC 容器完成 Bean 必要的创建后,调用 Bean 类提供的回调方法对 Bean 实例进一步处理。
- ⑨ destruction
该配置项是可选项,用于指定 IoC 容器在销毁 Bean 时,调用 Bean 类提供的回调方法。
2. Spring xml 配置文件
下面主要介绍基于XML的配置方式,基于注解和基于Java的配置放在后面进行讨论,放在后面讨论的原因是一些其它重要的Spring概念还需要掌握。
<?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的配置文件 -->
<bean id="student" class="spring.Student">
<property name="name" value="illusory"></property>
<property name="age" value="23"></property>
<property name="book" ref="book"></property>
</bean>
<bean id="book" class="spring.Book">
<property name="name" value="think in java"></property>
<property name="type" value="CS"></property>
</bean>
</beans>
3.2 注解方式
使用注解需要在xml配置文件中开启组件扫描
<!--配置组件扫描-->
<context:component-scan base-package="spring"/>
1.定义 bean
定义一个 bean 实体类或组件
@Component(value = "book")
public class Book {
private String type;
private String name;
//省略Getter/Setter和构造方法
}
2. 配置 bean
- 基本配置
@Component(value = "book")
public class Book {
private String type;
private String name;
//省略Getter/Setter和构造方法
}
其中@Component(value = "book")
相当于<bean id="book" class="spring.Book">
Bean实例的名称默认是Bean类的首字母小写,其他部分不变
- 属性注入
普通类型注入: @Value(value = "illusory")
引用类型注入: @Autowired/@Resources(name="")
@Component(value = "student")
public class Student {
@Value(value = "illusory")
private String name;
@Value(value = "23")
private int age;
@Autowired
private Book book;
}
@Component(value = "book")
public class Book {
@Value(value = "defaultType")
private String type;
@Value(value = "defaultName")
private String name;
}
3. 获取 bean
public static void main(String[] args) {
// 根据配置文件创建 IoC 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 从容器中获取 bean 实例
Student student = (Student) ac.getBean("student");
// 使用bean
System.out.println(student.getName());
//成功打印出 illusory
}
3.3 测试
/**
* @author illusory
* @version 1.0.0
* @date 2019/4/18
*/
public class SpringTest {
public static void main(String[] args) {
// 根据配置文件创建 IoC 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 从容器中获取 bean 实例 这里的名称就是配置文件中的id="student"
Student student = (Student) ac.getBean("student");
// 使用bean
System.out.println(student.getName());
//成功打印出 illusory
}
}
4. 简要分析
4.1 创建Spring IoC 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext .xml")
执行这句代码时 Spring 容器对象被创建,同时 applicationContext .xml
中配置的 bean 就会被创建到内存中。
4.2 Bean注入
Bean 注入的方式有两种;
- 一种是
在XML中配置
,此时分别有属性注入
、构造函数注入
和工厂方法注入
; - 另一种则是使用
注解
的方式注入:@Autowired
、@Resource
、@Required
。
1. 在xml文件中配置依赖注入
- 属性注入
属性注入即通过setXxx()方法注入Bean的属性值或依赖对象,属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。Spring先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。
由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。
<bean id="book" class="spring.Book">
<property name="name" value="think in java"></property>
<property name="type" value="CS"></property>
</bean>
例子中的这个就是属性注入。
- 构造方法注入
使用构造函数注入的前提是 Bean必须提供带参数的构造函数。
<bean id="book" class="spring.Book">
<constructor-arg name="name" value="think in java"></constructor-arg>
<constructor-arg name="type" value="CS"></constructor-arg>
</bean>
- 工厂方法注入
有时候 bean 对象不能直接 new,只能通过工厂方法创建。
/**
* @author illusory
* @version 1.0.0
* @date 2019/4/18 0018
*/
public class BookFactory {
//非静态方法
public Book createBook() {
Book book = new Book();
book.setName("图解HTTP");
book.setType("HTTP");
return book;
}
//静态方法
public static Book createBookStatic() {
Book book = new Book();
book.setName("大话数据结构");
book.setType("数据结构");
return book;
}
}
非静态方法:必须实例化工厂类(factory-bean)后才能调用工厂方法
<bean id="bookFactory" class="spring.BookFactory"></bean>
<bean id="book" class="spring.Book" factory-bean="bookFactory" factory-method="createBook"></bean>
静态方法:不用实例化工厂类(factory-bean)后才能调用工厂方法
<bean id="book" class="spring.Book" factory-method="createBookStatic"></bean>
4.3 获取 bean 实例
接着通过从 Spring 容器中根据名字获取对应的 bean 。
Student student = (Student) ac.getBean("student");
5. 小结
5.1 大致流程
1.定义bean:定义一个 bean 实体类或组件
2.配置 bean
- 基本配置 xml 配置文件中注册这个 bean
- 属性注入 xml 配置文件中为这个 bean 注入属性
- XML中配置 :
属性注入
、构造方法注入
、工厂方法注入
- 注解方式 :
@Autowired
、@Resource
、@Required
- XML中配置 :
3.获取 bean 实例:根据 name(即配置文件中的 bean id) 从 Spring 容器中获取 bean 实例
5.2 具体代码
1. 定义 bean
定义一个 bean 实体类或组件
public class Book {
private String type;
private String name;
//省略Getter/Setter和构造方法
}
2. 配置 bean
- 基本配置
<bean id="book" class="spring.Book">
</bean>
- 属性注入
<bean id="book" class="spring.Book">
<property name="name" value="think in java"></property>
<property name="type" value="CS"></property>
</bean>
3. 获取 bean
// 根据配置文件创建 IoC 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 从容器中获取 bean 实例
Student student = (Student) ac.getBean("student");
6. 参考
https://blog.csdn.net/u010648555/article/details/76299467
https://www.cnblogs.com/_popc/p/3972212.html
https://www.cnblogs.com/wnlja/p/3907836.html