详解Spring框架的核心思想之IOC

微信号:GitShare
微信公众号:爱折腾的稻草
如有问题或建议,请在公众号留言[1]

前续

为帮助广大SpringBoot用户达到“知其然,更需知其所以然”的境界,作者将通过SpringBoot系列文章全方位对SpringBoot2.0.0.RELEASE版本深入分解剖析,让您深刻的理解其内部工作原理。

No.1 Spring是什么

为了让更多的朋友了解Spring,首先科普一下Spring!有兴趣的朋友可以去Spring官网逛逛,地址是:https://spring.io/

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform.

Spring Framework为现代基于Java的企业应用程序提供了全面的编程和配置模型 - 在任何类型的部署平台上。

总的来说:Spring是一个分层的Java SE/EE应用一站式的轻量级开源框架。

No.2 Spring的优点

Spring的一个关键要素是应用程序级别的基础架构支持:Spring专注于企业应用程序的“管道”,以便团队可以专注于应用程序级业务逻辑,而无需与特定部署环境建立不必要的联系。

  • 方便解耦,简化开发,通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码造成的程序耦合度高。

  • AOP编程的支持,通过Spring提供的AOP功能,方便进行面向切面编程。

  • 声明式事务的支持,在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

  • 方便程序的测试,可以用非容器依赖的编程方式进行几乎所有的测试工作。

  • 方便集成各种优秀框架,Spring提供了对各种优秀框架的直接支持。

No.3 Sprnig的架构
详解Spring框架的核心思想之IOC

整个Spring框架按其所属功能可以划分为五个主要模块,这五个模块几乎为企业应用提供了所需的一切,从持久层、业务层到表现层都拥有相应的支持,这就是Spring为什么是一站式框架。IoC和AOP是Spring的核心。

1、核心模块(Core Container)
  • Spring的核心模块实现了IoC的功能,它将类和类之间的依赖从代码中脱离出来,用配置的方式进行依赖关系描述。 由IoC容器负责类的创建,管理,获取等。BeanFactory接口是Spring框架的核心接口,实现了容器很多核心的功能。

  • Context模块构建于核心模块之上,扩展了BeanFactory的功能,包括国际化,资源加载,邮件服务,任务调度等多项功能。ApplicationContext是Context模块的核心接口。

  • 表达式语言(Expression Language)是统一表达式语言(EL)的一个扩展,支持设置和获取对象属性,调用对象方法,操作数组、集合等。使用它可以很方便的通过表达式和Spring IoC容器进行交互。

2、AOP模块

Spring AOP模块提供了满足AOP Alliance规范的实现,还整合了AspectJ这种AOP语言级的框架。通过AOP能降低耦合。

3、数据访问集成模块(Data Access/Integration )

该模块包括了JDBC、ORM、OXM、JMS和事务管理

  • 事务模块:该模块用于Spring管理事务,只要是Spring管理对象都能得到Spring管理事务的好处,无需在代码中进行事务控制了,而且支持编程和声明性的事务管理。

  • JDBC模块:提供了一个JBDC的样例模板,使用这些模板能消除传统冗长的JDBC编码还有必须的事务控制,而且能享受到Spring管理事务的好处。

  • ORM模块:提供与流行的“对象-关系”映射框架的无缝集成,包括Hibernate、JPA、MyBatis等。而且可以使用Spring事务管理,无需额外控制事务。

  • OXM模块:提供了一个对Object/XML映射实现,将java对象映射成XML数据,或者将XML数据映射成java对象,Object/XML映射实现包括JAXB、Castor、XMLBeans和XStream。

  • JMS模块:用于JMS(Java Messaging Service),提供一套 “消息生产者、消息消费者”模板用于更加简单的使用JMS,JMS用于用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

4、Web模块

该模块建立在ApplicationContext模块之上,提供了Web应用的功能。如文件上传、FreeMarker等。
Spring可以整合Struts2等MVC框架。Spring自己提供了MVC框架Spring MVC。

5、测试模块

Spring可以用非容器依赖的编程方式进行几乎所有的测试工作,支持JUnit和TestNG等测试框架。

No.4 什么是IOC

IOC是Inversion of Control的缩写,也称为“控制反转”。1996年,Michael Mattson在一篇有关探讨面向对象框架的文章中,首先提出了IOC 这个概念。  
简单来说就是把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。  
IOC理论提出的观点大体是这样的:借助于“第三方”(IOC容器)实现具有依赖关系的对象之间的解耦。

2004年,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。
控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。

所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。  
依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

小结:
  • 所谓控制反转,就是把原先我们代码里面需要实现的对象创建、依赖的代码,反转给容器来帮忙实现。

  • IOC(Inversion of Control)另外一种说法叫DI(Dependency Injection),即依赖注入。它并不是一种技术实现,而是一种设计思想。

  • 从技术角度来看,IOC其实就是反射编程。通过类名(字符串)来动态生成类对象。

  • IoC容器:最主要是完成了对象的创建和依赖的管理注入。

No.5 Spring的IOC容器(BeanFaoctory体系)

BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范,其源码如下:

public interface BeanFactory {
    /**
     * 对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,如果需要得到工厂本身,需要转义
     */
    String FACTORY_BEAN_PREFIX = "&";
    /**
     * 根据bean的名字,获取在IOC容器中得到bean实例 
     */
    Object getBean(String name) throws BeansException;
    /**
     * 根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制
     */
    <T> getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
    /**
     * 根据bean的名字和Class类型来得到bean实例,args实例化bean时的参数
     */
    Object getBean(String name, Object... args) throws BeansException;
    /**
     * 根据bean的Class类型类获取bean实例
     */
    <T> getBean(Class<T> requiredType) throws BeansException;
    /**
     * 根据bean的Class类型类获取bean实例,args实例化bean时的参数
     */
    <T> getBean(Class<T> requiredType, Object... args) throws BeansException;
    /**
     * 提供对bean的检索,看看是否在IOC容器有这个名字的bean 
     */
    boolean containsBean(String name);
    /**
     * 根据bean名字得到bean实例,并同时判断这个bean是不是单例 
     */
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    /**
     * [2.0.3新增]根据bean名字得到bean实例,并同时判断这个bean是不是原型
     */
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    /**
     * 检查给定名称的getBean调用是否将返回可分配给指定目标类型的对象。
     */
    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    /**
     * [2.0.1版本新增]检查给定名称的getBean调用是否将返回可分配给指定目标类型的对象。 
     */
    boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
    /**
     * 得到bean实例的Class类型  
     */
    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    /**
     * 得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
     */
    String[] getAliases(String name);
}

用于访问Spring bean容器的根接口。  
BeanFactory实现应尽可能支持标准bean生命周期接口,完整的初始化方法及其标准顺序是:

1、BeanNameAware的setBeanName
2、BeanClassLoaderAware的setBeanClassLoader
3、BeanFactoryAware的setBeanFactory
4、EnvironmentAware的setEnvironment
5、EmbeddedValueResolverAware的setEmbeddedValueResolver
6、ResourceLoaderAware的setResourceLoader(仅适用与运行时的应用上下文) 
7、ApplicationEventPublisherAware的setApplicationEventPublisher (仅适用与运行时的应用上下文) 
8、MessageSourceAware的setMessageSource (仅适用与运行时的应用上下文) 
9、ApplicationContextAware的setApplicationContext (仅适用与运行时的应用上下文) 
10、ServletContextAware'的setServletContext (仅适用与运行时的应用上下文) 
- 11、 BeanPostProcessors的postProcessBeforeInitialization方法
- 12、InitializingBean的afterPropertiesSet
- 13、自定义一个初始化方法(init-method)
- 14、BeanPostProcessors的postProcessAfterInitialization方法

关闭BeanFactory时,以下生命周期方法适用:

1、DestructionAwareBeanPostProcessors的postProcessBeforeDestruction方法
2、DisposableBean's destroy 
- 3、自定义一个销毁方法(destroy-method)
1、BeanFactory的继承关系
详解Spring框架的核心思想之IOC
  • ListableBeanFactory  
    BeanFactory接口的扩展由bean工厂实现,提供容器内bean实例的枚举功能。

  • HierarchicalBeanFactory  
    可以被作为分层结构中的一部分的bean工厂实现。提供父容器的访问功能。

public interface HierarchicalBeanFactory extends BeanFactory {
    /**
     * 返回其父工厂,如果没有返回Null
     */
    @Nullable
    BeanFactory getParentBeanFactory();
    /**
     * 返回当前bean工厂上下文是否存在给定bean名字的bean,忽略定义在其继承层次中的工厂上下文,只在当前层次中查找
     */
    boolean containsLocalBean(String name);

}
  • AutowireCapableBeanFactory  
    BeanFactory接口的扩展将由能够自动装配的BeanFactory实现,前提是他们希望为现有bean实例公开此功能。
    添加集成其他框架功能。如果集成WebWork则可以使用Spring对Actions等进行管理。

  • SimpleJndiBeanFactory
    基于JNDI的简单实现Spring的BeanFactory接口,不支持枚举bean定义。

  • ConfigurableBeanFactory  
    是HierarchicalBeanFactory的子类,在其基础上提供了配置BeanFactory的功能。

  • ConfigurableListableBeanFactory  
    是ListableBeanFactory、ConfigurableBeanFactory和AutowireCapableBeanFactory的子类,它提供了分析和修改bean定义以及预先实例化单例的功能。

  • ApplicationContext  
    应用上下文接口,这个在Spring的Context一文中已经分析过了。

2、Spring中IOC容器的初始化

在Spring中IOC容器的初始化是有refresh()方法来启动的,主要有三个基本过程:

  • 1.BeanDifinition的Resource定位

  • 2.BeanDifinition的载入与解析

  • 3.BeanDifinition在Ioc容器中的注册  

No.6 IOC容器的缺点

IOC给我们带来的优点就不说了,主要看看其注意事项:

  • 项目中引人第三方的IOC容器,对象的生成变得复杂;

  • 由于IOC容器是通过反射来生成对象,所以会有一定的性能损耗;

  • Spring的IOC容器在使用时,需要配置大量的配置文件。

后记

为帮助广大SpringBoot用户达到“知其然,更需知其所以然”的境界,作者将通过SpringBoot系列文章全方位对SpringBoot2.0.0.RELEASE版本深入分解剖析,让您深刻的理解其内部工作原理。

本系列历史文章列表
  • 1、[SpringBoot]利用SpringBoot快速构建并启动项目

  • 2、[SpringBoot]详解SpringBoot应用的启动过程

  • 3、[SpringBoot]深入浅出剖析SpringBoot的应用类型识别机制

  • 4、[SpringBoot]深入浅出剖析SpringBoot中Spring Factories机制

  • 5、[SpringBoot]详解SpringBoot中SpringApplication的run方法的前三步

  • 6、[SpringBoot]图解Spring的Environment机制

  • 7、[SpringBoot]源码解析SpringBoot应用Environment的构造过程

  • 8、[SpringBoot]源码解析SpringBoot的Banner机制

  • 9、[SpringBoot]图解SpringBoot的应用上下文机制

  • 10、[SpringBoot]源码分析SpringBoot的异常处理机制

  • 11、[SpringBoot]源码解析SpringBoot应用上下文的刷新处理

  • 12、[SpringBoot]源码解析SpringBoot应用上下文前置处理

  • 13、[SpringBoot]图解Spring的核心组件之Context

  • 14、[SpringBoot]详解Spring的核心思想之AOP


详解Spring框架的核心思想之IOC

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要介绍了spring的事务传播属性REQUIRED_NESTED的原理介绍,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。传统事务中回滚点的使...
今天小编给大家分享的是一文解析spring中事务的传播机制,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获...
这篇文章主要介绍了SpringCloudAlibaba和SpringCloud有什么区别,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。Spring Cloud Netfli...
本篇文章和大家了解一下SpringCloud整合XXL-Job的几个步骤。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。第一步:整合pom文件,在S...
本篇文章和大家了解一下Spring延迟初始化会遇到什么问题。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。List 坑列表 = new ArrayList(2);...
这篇文章主要介绍了怎么使用Spring提供的不同缓存注解实现缓存的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇...
本篇内容主要讲解“Spring中的@Autowired和@Resource注解怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学...
今天小编给大家分享一下SpringSecurity怎么定义多个过滤器链的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家
这篇文章主要介绍“Spring的@Conditional注解怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Spring的@Con...
这篇文章主要介绍了SpringCloudGateway的熔断限流怎么配置的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringCloud&nb...
今天小编给大家分享一下怎么使用Spring解决循环依赖问题的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考
这篇文章主要介绍“Spring事务及传播机制的原理及应用方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Sp...
这篇“SpringCloudAlibaba框架实例应用分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价
本篇内容主要讲解“SpringBoot中怎么使用SpringMVC”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习...
这篇文章主要介绍“SpringMVC适配器模式作用范围是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“SpringMVC
这篇“导入SpringCloud依赖失败如何解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家...
这篇文章主要讲解了“SpringMVC核心DispatcherServlet处理流程是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来
今天小编给大家分享一下SpringMVCHttpMessageConverter消息转换器怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以...
这篇文章主要介绍“Spring框架实现依赖注入的原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Spring框架...
本篇内容介绍了“Spring单元测试控制Bean注入的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下