文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
1. 概述
1.1 IoC 理论
- IoC(Inversion of Control)翻译为 控制反转,不是什么技术,而是一种设计思想。
- 在 Java 开发中,IoC 意味着将设计好的对象交给容器控制,而不是传统的在对象内部直接控制。
- 由 Spring IoC 容器 来负责对象的生命周期和对象之间的关系。
- 传统程序设计都是主动去创建相关对象然后再组合起来。
- 在传统的开发模式下,都是采用直接 new 一个对象的方式来创建对象,也就是说依赖的对象直接由自己控制。
- 对象中主动去创建被依赖的对象,这是正转。
- 有了 loC 容器,客户端类中不再主动创建对象。
- 直接由 IoC 容器来控制对象。
- 所依赖的对象直接由 IoC 容器创建后注入到被注入的对象中,依赖的对象由原来的主动获取变成被动接受,所以是 反转(所依赖对象的获取被反转)。
1.1.1 IoC 和 DI
- DI(Dependency Injection)即 依赖注入,组件之间依赖关系由容器在运行期决定。由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。
- IoC 和 DI 是 同一个概念的不同角度描述。
- 依赖注入 明确描述了 被注入对象依赖 IoC 容器配置依赖对象。
1.1.2 注入形式
- IoC Service Provider 为被注入对象提供被依赖对象有几种方式:构造方法注入、stter 方法注入 和 接口注入。
构造器注入(Constructor Injection)
- 被注入的对象通过在其构造方法中声明依赖对象的参数列表,让外部知道它需要哪些依赖对象。
- 构造器注入方式比较直观,对象构造完毕后就可以直接使用。
public class UserRegister {
private UserDao userDao = null;//由容器通过构造函数注入的实例对象
public UserRegister(UserDao userDao){
this.userDao = userDao;
}
}
setter 方法注入(Setter Injection)
- 对于 JavaBean 对象而言,一般都是通过 getter 和 setter 方法来访问和设置对象的属性。所以,当前对象只需要为其所依赖的对象提供相对应的 setter 方法,就可以通过该方法将相应的依赖对象设置到被注入对象中。
- 相比于构造器注入,setter 方式注入会显得比较宽松灵活,它可以在任何时候进行注入(在使用依赖对象之前)
public class UserRegister {
private UserDao userDao = null;//该对象实例由容器注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
接口方式注入(Interface Injection)
- 需要被依赖的对象实现不必要的接口,带有侵入性。
public interface InjectUserDao {
public void setUserDao(UserDao userDao);
}
public class UserRegister implements InjectUserDao{
private UserDao userDao = null;//该对象实例由容器注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
2. 框架结构
- Spring 由 20 多个模块组成,它们可以分为核心容器(Core Container)、数据访问/集成(Data Access/Integration)、Web、面向切面编程(AOP, Aspect Oriented Programming)、设备(Instrumentation)、消息发送(Messaging)和测试(Test)。
2.1 核心容器(Core Container)
- 包含以下模块。
- spring-core 提供依赖注入 IoC 与依赖注入的最基本实现。
-
spring-beans 提供 Bean 工厂与 Bean 的装配。
- 提供对 Factory 模式的经典实现来消除对程序性单例模式的需要,并真正地允许从程序逻辑中分离出依赖关系和配置。
-
spring-context 提供 spring 的 context 上下文,即 IoC 容器。
- 提供了用一种框架风格地方式来访问对象,有些像 JNDI 注册表。
- 还增加了国际化(I18N),事件传播,资源装载,以及透明创建上下文,例如通过 servlet 容器,以及对大量 JavaEE 特性的支持,如 EJB、JMX,核心接口是
ApplicationContext
。
-
spring-expression 提供 spring 表达式语言,提供了在运行期间查询和操作对象图的强大能力。
- 支持访问和修改属性值,方法调用。
- 支持访问及修改数组、容器和索引器,命名变量。
- 支持算数和逻辑运算。
- 支持从 spring 容器获取 Bean。
- 支持列表投影、选择和一般的列表聚合等。
- spring-context-support 为集成第三方库(如定时器 Quartz)提供支持。
- 因为 spring-core 依赖 commons-logging,而其他模块都依赖 spring-core,所以整个 spring 框架都依赖 commons-logging,如果有自己的日志实现,如 log4j,可以排除对 commons-logging 的依赖,没有日志实现而排除了 commons-logging 依赖,编译会报错。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.18.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
2.2 数据访问/集成(Data Access/Integration)
- 包含以下模块。
-
spring-jdbc 提供 JDBC 的支持。
- 是 Spring 对 JDBC 数据访问的封装,提供了一个 JDBC 抽象层,消除了冗长代码。
-
spring-tx 提供事务控制。
- 支持编程和声明性事务管理。
- spring-orm 对象关系映射,集成 ORM 框架。
-
spring-oxm 对象 XML 映射。
- 目的在于 Java 对象(POJO)和 XML 文档之间来回转换。
-
spring-jms Java 消息服务。
- 用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
-
spring-jdbc 提供 JDBC 的支持。
2.3 Web
- 包含以下模块。
- spring-web 提供基础 web 功能,如文件上传,使用 servlet listeners 初始化 IoC 容器等。
- spring-webmvc 提供 MVC 实现(SpringMVC)。
- spring-webmvc-portlet 提供基于 portlet 的 MVC 实现。
- spring-websocket 为 web 应用提供的高效通信工具。
2.4 面向切面编程(AOP)
- 包含以下模块。
-
spring-aop 面向切面编程。
- 提供了符合 aop 联盟规范的面向切面的编程实现,可以定义如方法拦截器和切入点,从逻辑上讲,可以减弱代码的功能耦合,清晰地被分离开。
- 利用源码级地元数据功能,还可以将各种行为信息合并到代码中。
- spring-aspects 集成 AspectJ,这是一个功能强大且成熟的面向方面编程(AOP)框架。
-
spring-aop 面向切面编程。
2.5 设备(Instrumentation)
- 包含以下模块。
- spring-instrument 提供一些类级的工具支持和 ClassLoader 级的实现,用于服务器。
- spring-instrument-tomcat 针对 tomcat 的 instrument 实现。
2.6 消息发送(Messaging)
- 包含以下模块。
- spring-messaging 用于构建基于消息的应用程序,为集成 messaging API 和消息协议提供支持。
2.7 测试(Test)
- 包含以下模块。
- spring-test 支持使用 JUnit 和 TestNG 对 Spring 组件进行测试。
3. 相关组件
3.1 Resource(core)
-
org.springframework.core.io.Resource 是对资源的抽象。
- 它的每一个实现类都代表了一种资源的访问策略,如
ClassPathResource
、UrlResource
、FileSystemResource
、ByteArrayResource
、InputStreamResource
。
- 它的每一个实现类都代表了一种资源的访问策略,如
- 以上接口或类都归属于 spring-core。
3.2 ResourceLoader(core)
- Spring 利用 org.springframework.core.io.ResourceLoader 进行统一资源加载。
- 以上接口或类都归属于 spring-core。
3.3 BeanFactory(beans)
-
org.springframework.beans.factory.BeanFactory 是一个 bean 容器,是 IoC 必备的数据结构,其中
BeanDefinition
是它的基本结构。 -
BeanFactory
内部维护着一个BeanDefinition
的 map ,并可根据BeanDefinition
的描述进行 bean 的创建和管理。
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
- 不同的 Factory 是为了区分在 Spring 内部操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。
-
ListableBeanFactory
接口表示这些 Bean 是可列表的。 -
HierarchicalBeanFactory
接口表示这些 Bean 是有继承关系的,每个 Bean 都有可能有父 Bean。 -
AutowireCapableBeanFactory
接口定义 Bean 的自动装配规则。
-
- 这几个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为。
- 以上接口或类都归属于 spring-beans。
BeanFactory 提供的主要方法名称 | 说明 |
---|---|
getBean() |
多个方法用于获取配置给 Spring loc 容器的 bean。 |
isSingleton() |
用于判断是否单例,为真时,容器中单例。 |
isPrototype() |
与单例相反,为真时,每次 getBean,创建新的实例。 |
getAliases() |
获取别名。 |
3.4 BeanDefinition(beans)
- org.springframework.beans.factory.config.BeanDefinition 用于描述 Spring 中的 Bean 对象。
- 以上接口或类都归属于 spring-beans。
3.5 BeanDefinitionReader(beans)
-
org.springframework.beans.factory.support.BeanDefinitionReader 的作用是读取 Spring 的配置文件的内容,并将其转换成 Ioc 容器内部的数据结构
BeanDefinition
。
- 以上接口或类都归属于 spring-beans。
3.6 ApplicationContext(context)
-
org.springframework.context.ApplicationContext 是 Spring 容器,也叫做应用上下文,与应用息息相关。它继承
BeanFactory
,是BeanFactory
的扩展。- 继承 org.springframework.context.MessageSource 接口,提供国际化的标准访问策略。
- 继承 org.springframework.context.ApplicationEventPublisher 接口,提供 事件 机制。
- 扩展
ResourceLoader
,可以用来加载多种Resource
,可以灵活访问不同的资源。 - 对 web 应用的支持。
- 以上黄色接口或类归属于 spring-beans。
- 以上绿色接口或类归属于 spring-context。
- 以上红色接口或类归属于 spring-core。
- 以上蓝色接口或类归属于 spring-web。
3.7 小结
- IoC 主要由 spring-core、spring-beans 和 spring-context 项目进行实现。
网友评论