技术体系架构

单一架构

一个项目,一个工程,导出一个war包,在一个Tomcat上运行

  • 应用框架:SpringSpringMVCMybatis
  • SpringMVC 在表述层简化跟前端的交互
  • Spring 每一层都有
  • MybatisJDBC的封装,在持久化层简化操作
    single

分布式架构

一个项目,多个模块,每个模块是一个module,每个工程都运行在自己的Tomcat上,模块之间可以相互调用,每个模块可以看作是一个单一架构

  • SpringBoot是对SSM的封装和简化,节省创建过程
  • SpringCloud维护服务之间的互相调用
    distributed
  • 框架 = jar包 + 配置文件 = 反射 + 注解 + 设计模式

SpringFramework主要功能模块

功能模块 介绍
Core Container 核心容器,Spring环境下所有的功能都必须基于IoC容器,实现对象管理
AOP & Aspects 面向切面编程,对面向对象编程的完善
TX 声明式事务管理
Spring MVC 提供面向Web应用程序的集成功能

IoC核心容器

Spring帮助完成组件管理IoC,包括组件对象实例化,组件属性赋值,组件对象引用,组件对象存活周期管理…

  • 组件一定是对象,对象未必是组件,组件是映射到应用程序中所有可重用组件Java对象

IoC概念(`Inversion of Control) 控制反转

  • 主要针对对象的创建和调用控制而言,当应用程序需要使用一个对象的时候,不再是应用程序直接创建该对象,而是由IoC容器来创建和管理
  • 控制权由应用程序转移到IoC容器,实现了反转。
  • 基本通过依赖查找方式实现,即IoC容器维护着构成应用程序的对象,负责创建这些对象

DI概念(Dependency Injection) 依赖注入

  • 组件之间传递依赖关系的过程中,将依赖关系在容器内部进行处理,不必在应用程序代码中硬编码对象之间的以来关系,实现对象之间的耦合
  • SpringDI是通过XML配置文件或者注解方式实现的,提供三种形式的依赖注入:Setter方法注入,构造函数注入,接口注入

优点

  1. 解耦合,通过依赖注入减少依赖关系
  2. 提高可复用性
  3. 通过XML文件或者注解进行配置管理
  4. 通过Spring管理的对象可以使用框架其他功能(AOP等)

IoC容器具体接口和实现类

  • BeanFactory接口提供了高级配置机制,可以管理任何类型对象,是Spring IoC容器的标准化超接口
  • ApplicationContextBeanFactory的子接口,扩展了以下功能
    • 更容易与Spring AOP功能集成
    • 消息资源处理(国际化)
    • 特定于应用程序给予接口实现,比如Web应用程序的WebApplicationContext
  • BeanFactory提供了配置框架和基本功能,ApplicationContext添加更多特定功能,后者是前者的完整超集
类型名 介绍
ClassPathXmlApplicationContext 通过读取类路径下的XML格式配置文件创建IoC容器对象,类路径下的resources
FileSystemXmlApplicationContext 通过文件系统路径读取XML格式配置文件创建IoC容器对象
AnnotationConfigApplicationContext 通过读取Java配置类创建IoC容器对象
WebApplicationContext 专门为Web应用准备,基于Web环境创建IoC容器对象,将对象引入存入ServletContext
  • Spring框架提供了多种配置方式
    • XML配置方式,最早期就有,配置和解析比较复杂,逐渐不使用
    • 注解方式,2.5版本开始存在,在Bean上使用注解替代XML配置信息,将Bean注册到Spring IoC容器中
    • Java配置类方式,3.0版本开始,使用Java编写配置信息,通过@Configuration, @Bean等注解实现Bean和依赖关系的配置

IoC/DI实现步骤

  1. 配置元数据
  • 基于XML的配置元数据基本结构
  • id属性标识单个Bean定义的字符串,随便取,只需要不重复即可
  • class属性定义Bean类型并使用全限定类名
  • 如果一个组件类,声明两个组件信息,默认是单例模式,会实例化两个组件对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="..." [1] class="..." [2]>
<!-- collaborators and configuration for this bean go here -->
</bean>

<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
  1. 实例化IoC容器
  • 提供给ApplicationContext构造函数的位置路径是资源字符串地址,允许容器从各种外部资源加载配置元数据
1
2
3
//实例化ioc容器,读取外部配置文件,最终会在容器内进行IoC和DI动作
ApplicationContext context =
new ClassPathXmlApplicationContext("services.xml", "daos.xml");
  1. 获取Bean(组件)
  • ApplicationContext是一个高级工厂接口,能够维护不同的Bean以及其依赖项的注册表
  • 使用T getBean(String name, Class<T> requiredType)可以检索Bean实例
1
2
3
4
5
6
//创建IoC容器对象,指定配置文件,IoC也开始实例组件对象
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
//获取IoC容器的组件对象
PetStoreService service = context.getBean("petStore", PetStoreService.class);
//使用组件对象
List<String> userList = service.getUsernameList();
  • 无参构造函数实例化配置只需要<bean id class />
  • 静态工厂类IoC配置 <bean id class factory-method="静态工厂方法"/>
  • 非静态工厂IoC配置
    • <bean id="A" class/>
    • <bean id="B" factory-bean="A" factory-method="静态工厂方法"/>
  • FactoryBean不需要再指定factory-method
    • FactoryBean<T>提供了三种方法
    • T getObject() 返回工厂的对象实例,返回值存储到IoC容器中,在内部编写复杂的实例化过程
    • boolean isSingleton() 如果FactoryBean返回单例,则返回true,默认实现返回true,否则返回false
    • Class<?> getObjectType() 返回getObject()方法返回的对象类型,不知道对象类型则返回null
    • 用于代理类场景,第三方框架整合,复杂对象实例化
    • 工厂bean的标识就是&id

FactoryBean VS BeanFactory

  • FactoryBeanSpring中特殊的Bean,可以在getObject()工厂方法自定义逻辑创建Bean,能够生产其他BeanBean
  • 容器启动时创建,实际使用通过调用getObject()得到生产的Bean,可以自定义任何初始化逻辑
  • BeanFactorySpring框架基础,顶级接口定义了容器的基本行为,例如管理bean的生命周期,配置文件的加载和解析,bean的装配和依赖注入
  • 提供了访问bean的方式,比如getBean()指定获取bean的实例,从不同来源获取bean定义,将其转换为bean实例
  • 包含很多子类,比如ApplicationContext接口
  • 前者创建Bean的接口,提供灵活初始化功能,后者管理bean的框架基础接口,提供容器基本功能和bean生命周期管理

Bean依赖注入配置DI

  1. 配置IoC
  2. 配置DI
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    <!-- 无参构造函数声明IoC -->
    <bean id="A" class />
    <!-- 单构造参数注入 -->
    <bean id="B" class>
    <!-- value表示值,此处用不上 -->
    <!-- ref 表示对另一个IoC对象的引用 -->
    <constructor-arg ref="A">
    </bean>
    <!-- 多构造参数注入 -->
    <bean id="B1" class>
    <!-- 按照顺序赋值 -->
    <constructor-arg value="">
    <constructor-arg value="">
    <constructor-arg ref="A">
    </bean>
    <bean id="B2" class>
    <!-- 按照参数名 -->
    <constructor-arg name="" value="">
    <constructor-arg name="" value="">
    <constructor-arg name="" ref="A">
    </bean>
    <bean id="B2" class>
    <!-- 按照参数下标 -->
    <constructor-arg index="1" value="">
    <constructor-arg index="0" value="">
    <constructor-arg index="2" ref="A">
    </bean>
    <!-- setter方法注入 -->
    <bean id class>
    <!-- name 是setter方法去掉set和,并且首字母小写的值 -->
    <!-- value ref 同样二选一 -->
    <property name ref value>
    </bean>
  • Spring IoC是一个高级容器,会先创建对象(IoC),在进行赋值(DI)
  • 因此先后顺序没有关系

读取`IoC组件信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 方式1 创建时指定xml文件即可,可以指定多个,或者一个,也可以无参
ApplicationContext aC = new ClassPathXmlApplicationContext("location1","location2",...);
// 方式2 一般是源码的配置过程
ClassPathXmlApplicationContext aC1 = new ClassPathXmlApplicationContext();
aC1.setConfigLocations("locations");
aC1.refresh();//调用IoC和DI的流程

// 方式1 直接根据bean id获取,返回类型是Object 需要强制类型转换,不推荐
Object h = aC1.getBean("id");
// 方式2 根据bean id获取,同时指定类型
H h1 = aC1.getBean("id", H.class);
// 方式3 根据类型获取,但是同一个类型在IoC容器中只能存在一个,否则报错NoUniqueBeanDefinitionException
// IoC的配置一定是实现类,不能是接口,但是可以根据接口获取值,因为使用了instance of 获取容器类型,接口和实现类的instance of 是相同的
H h2 = aC1.getBean(H.class);

h2.doWork();

Bean组件的作用域和周期方法配置

  • 组件类中定义方法,当IoC容器实例化和小会组件对象的时候调用
  • 组件声明<bean>只是将Bean信息配置给IoC容器,在容器中,bean标签对应的信息转成Spring内部的BeanDefinition对象
  • 包含定义的信息id,class,属性,创建多少个Bean实例对象,由BeanScope属性指定
作用域 含义 创建对象时机 默认
singleton IoC容器中,这个bean对象始终为单例 IoC容器初始化时
propotype IoC容器中,这个bean对象有多个实例 获取bean
request 请求范围内有效的实例 每次请求
propotype 会话范围内有效的实例 每次会话