文档章节

Spring IoC学习

a
 ancle
发布于 2015/12/29 23:07
字数 2460
阅读 31
收藏 0
点赞 0
评论 0

IoC是什么

IoC-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想。Java开发中,IoC意味着将设计好的对象交给IoC容器控制,不再是传统的在对象内部直接控制。

  • 谁控制谁,控制什么

    传统Java SE程序中,直接在对象内部通过new创建对象,由程序主动去创建依赖对象;

    IoC机制有专门的一个容器来创建这些对象,由IoC容器来控制对象的创建;

    谁控制谁?IoC容器控制对象;

    控制什么?主要控制了外部资源的获取(不只是对象包括比如文件等)

  • 为何是反转,哪些方面反转了

    传统的应用程序,在对象中主动控制去直接获取依赖对象,也就是正转;

    反转则是由IoC容器帮忙创建及注入依赖对象;

    为何是反转?由容器进行查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;

    哪些方面反转了?依赖对象的获取被反转了


IoC能做什么

    传统的应用程序在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;

    IoC容器,把创建和查找依赖对象的控制权交给了容器,由容器进行注入,组合对象,所以对象与对象间是松耦合;

    IoC很好的体现了面向对象设计法则之一 ——好莱坞法则:别找我们,我们找你;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找


IoC 和 DI

DI - Dependency Injection,依赖注入:组件之间的依赖关系由容器在运行期间决定,形象的说,由容器动态的将某个依赖关系注入到组件中。

通过依赖注入机制,只需简单的配置,就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处。

关键点:

  • 谁依赖于谁:当然是应用程序依赖IoC容器

  • 为什么需要依赖:应用程序需要IoC容器提供对象需要的外部资源

  • 谁注入谁:IoC容器注入应用程序某个对象,应用程序依赖的对象

  • 注入了什么:注入某个对象所需的外部资源(包括对象、资源、常量数据)


IoC 和 DI关系,其实是同一概念的不同角度描述,由于控制反转概念比较含糊,2004年又给出新的名字:依赖注入,相对IoC而言,”依赖注入“明确描述了”被注入对象依赖IoC容器配置依赖对象


Spring IoC容器的依赖,有两层含义:Bean依赖IoC容器容器注入Bean的依赖资源

Bean依赖容器,指的是容器负责创建并管理Bean,是Bean和IoC容器间的依赖关系

容器注入Bean的依赖资源,依赖资源可以是Bean、外部文件、常量数据等,由容器负责组装Bean之间的依赖关系,此处的依赖为Bean之间的依赖关系,可认为是传统的类与类关联、聚合、组合关系


Spring IoC容器实现依赖资源注入的方式

构造器注入:容器在实例化Bean时注入所需依赖资源,通过配置文件定义Bean中指定构造函数参数进行注入

setter注入:通过构造器、静态工厂或实例工厂实例好Bean后,通过调用Bean类的setter方法进行注入依赖

方法注入:通过配置方式替换掉Bean方法,也就是通过配置改变Bean方法功能


Spring IoC容器注入配置简写

一、构造器注入

    1)常量值

        简写:<constructor-arg index="0" vlaue="xxx" />

        全写:<constructor-arg index="0"><value>xxx</value></constructor-arg>

    2)引用

        简写:<constructor-arg index="0" ref="bean name" />

        全写:<constructor-arg index="0"><ref bean="bean name" /></constructor-arg>

二、setter注入

    1) 常量

        简写:<property index="0" value="xxx" />

        全写:<property index="0"><value>xxx</value></property>

    2) 引用

        简写:<property index="0" ref="bean name" />

        全写:<property index="0"><ref bean="bean name" /></property>

    3) 数组(array)

        <property name="array name">

            <array value-type="java.lang.String">

                <value>xxx</value>

                xxx

            </array>

        </property>

    4) 列表(List)

    <property name="list name">

        <list value-type="java.lang.String">

            <value>xxx</value>

            ...

        </list>

    </property>

    5) 集合(set)

        <property name="set name">

            <set>

                <value>xxx</value>

                ...

            </set>

        </property>

    5) 字典(map)

        <property name="map name">

            <map key-type="java.lang.String" value-type="java.lang.String">

                <entry key="xxx" value="xxx" />

                ...

            </map>

        </property>

    6) Properties


三、使用P命名空间简化setter注入

    <beans xmlns:p="http://www.springframework.org/schema/p"> //指定P命名空间

        <bean id="bean" class="com.spring.constroller.XXX" p:id="value" />

        //常量setter注入方式,等价于<property name="id" value="value" />


        <bean id="bean2" class="com.spring.controller.XXX" p:id-ref="xxx" />

        //引用setter注入方式,其等价于<property name="id" ref="xxx" />

    </beans>


BeanFactory和ApplicationContext

Spring通过xml配置文件描述Bean和Bean直接的依赖关系,利用Java语言的反射机制实例化Bean并建立Bean之间的依赖关系。

BeanFactory(org.springframework.beans.factory.BeanFactory)是Spring框架最核心的接口,提供了高级IoC的配置机制。

ApplicationContext(应用上下文,org.springframework.context.ApplicationContext)建立在BeanFactory基础上,提供了面向应用的gongneng,提供了国际化支持和框架事件体系。

一般地,称BeanFactory为IoC容器,而称ApplicationContext为应用上下文

从用途上进行划分,BeanFactory是Spring框架的基础设施,面向SpringApplicationContext面向Spring框架的使用者


初始化BeanFactory

使用Spring配置文件提供配置信息,通过BeanFactory装载配置文件,启动Spring IoC容器。

通过BeanFactory启动IoC容器时,并不会初始化配置文件中的Bean,初始化动作发生在第一个调用时。

注意初始化BeanFactory时,必须提供一种日志框架,比如Log4j,在类路径下提供Log4j配置文件,这样启动Spring容器才不会报错


ApplicationContext介绍

如若BeanFactory是Spring的心脏,那ApplicationContext就是Spring完整的身躯。ApplicationContext由BeanFactory派生而来,提供了面向实际应用的功能。

ApplicationContext体系结构

其主要实现类是ClassPathXMLApplicationContextFileSystemXMLApplicationContext,前者默认从类路径加载配置文件,后者从文件系统中装载配置文件。


ApplicationContext初始化

和BeanFactory初始化相似,ApplicationContext初始化也很简单,如果配置文件放在类路径下,优先使用ClassPathXMLApplicationContext实现类:

ApplicationContext context = new ClassPathXMLApplicationContext("com/bbtao/context/beans.xml");

等同于: "classpath:com/bbtao/context/beans.xml"

如果配置文件放在文件系统路径下,优先考虑FileSystemXMLApplicationContext实现类:

ApplicationContext context = new FileSystemXMLApplicationContext("com/bbtao/context/beans.xml");

等同于: "file:com/bbtao/context/beans.xml"


ApplicationContext与BeanFactory的重大区别

BeanFactory在初始化IoC容器时,并未实例化Bean,直到第一次访问调用某个Bean时才进行实例化操作;

ApplicationContext,在初始化应用上下文时就实例化所有单实例的Bean


AnnotationConfigApplicationContext

Spring 3.0支持基于类注解的配置方式,主要功能源自Spring的JavaConfig子项目。一个标注@Configuration注解的POJO即可提供Spring所需的Bean配置信息

Spring为基于注解类的配置提供了专门的ApplicationContext实现类:AnnotationConfigApplicationContext


WebApplicationContext

WebApplicationContext,专为Web应用准备的,允许从相对于Web根目录的路径中装载配置文件完成初始化工作

整个WebApplicationContext对象作为属性放到ServletContext中,以便Web应用环境可以访问到Spring应用上下文。为此,Spring提供一个工具类WebApplicationContextUtils,通过该类的getWebApplicationContext(ServletContext sc),就可从ServletContext中获取WebApplicationContext实例。


Spring 2.0在WebApplicationContext中为Bean添加了三个新的作用域:request作用域、session作用域和global session作用域。

WebApplicationContext中定义了一个常量ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,上下文启动时,WebApplicationContext实例以此放置在ServletContext的属性列表中。因此,通过以下语句从Web容器中获取WebApplicationContext:

    WebApplicationContext context = (WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

WebApplicationContext初始化

初始化方式,和BeanFactory、ApplicationContext有所不同,因为WebApplicationContext初始化时需要ApplicationContext实例,也就是说WebApplicationContext必须在拥有Web容器的前提下才能完成启动工作。

Spring提供了用于启动WebApplicationContext的Servlet和Web容器监听器

  • org.springframework.web.context.ContextLoaderServlet

  • org.springframework.web.context.ContextLoaderListener

两者内部都实现了启动WebApplicationContext实例的逻辑,根据Web容器的情况,在web.xml文件中进行配置就可以了

示例(ContextLoaderListener)

<!-- 指定Spring配置文件 -->

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContext.xml</param-value>

</context-param>

<!-- 声明Web容器监听器 -->

<listener>

    <listener-class>org.springframe.web.context.ContextLoaderListener</listener-class>

</listener>

ContextLoaderListener通过Web容器上下文参数contextConfigLocation获取Spring配置文件的位置。用户也可以指定多个配置文件,用逗号空格冒号分割均可。


不支持容器监听器的低版本Web容器中,采用ContextLoaderServlet完成启动工作:

示例(ContextLoaderServlet):

<!--  指定Spring配置文件 -->

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContext.xml</param-value>

</context-param>

<!-- 声明自动启动的Servlet -->

<servlet>

    <servlet-name>contextLoaderServlet</servlet-name>

    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>

    <!--  启动顺序 -->

    <load-on-startup>1</load-on-startup>

</servlet>


由于WebApplicationContext需要使用日志功能,将Log4j的配置文件放到类路径(/WEB-INF/classess/)下,Log4j引擎可顺利启动。如果Log4j配置文件放在其他位置,那必须在web.xml中指定配置文件位置

Spring为Log4j引擎提供了两个实现类:Log4jConfigServlet,和Log4jConfigListener;不管采用哪种方式,必须保证Log4j配置信息先于Spring配置文件加载

示例:

 <!-- 指定Spring配置文件 -->

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContex.xml</param-value>

</context-param>

<!-- 指定Log4j配置文件 -->

<context-param>

    <param-name>log4jConfigLocation</param-name>

    <param-value>/WEB-INF/log4j.properties</param-value>

</context-param>

<!--  配置Log4j的自启动Servlet -->

<servlet>

    <servlet-name>log4jConfigServlet<servlet-name>

    <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class>

    <!-- 指定Log4jConfigServlet的启动顺序,一定要先于WebApplicationContext启动 -->

    <load-on-startup>1</load-on-startup>

</serlvet>

<!-- 声明WebApplicationContext的自启动Servlet-->

<servlet>

    <servlet-name>contextLoaderServlet</servlet-name>

    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>

    <load-on-startup>2</load-on-startup>

</servlet>

如果使用Web监听器,则必须将Log4jConfigListener放在ContextLoaderListener前面,这样才保证Log4j的启动先于WebApplicationContext完成。


© 著作权归作者所有

共有 人打赏支持
a
粉丝 1
博文 53
码字总数 43568
作品 0
太原
Spring IOC 容器源码分析系列文章导读

1. 简介 Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本。经过十几年的迭代,现在的 Spring 框架已经非常成熟了。Spring 包含了众多模块,包括但不限于...

coolblog ⋅ 05/30 ⋅ 0

阿里老司机带你使用Spring框架快速搭建Web工程项目

摘要:Spring 框架是一个开源的 Java 平台,它为容易而快速的开发出耐用的 Java 应用程序提供了全面的基础设施。借助于Spring框架可以快速搭建Web工程项目,本文中阿里巴巴高级开发工程师嵛山...

萌萌怪兽 ⋅ 05/15 ⋅ 0

SpringBoot的幕后推手...

一、背景   这两年随着微服务的盛行,SpringBoot框架水到渠成的得到了高曝光,作为程序猿的我们,现在要是不知道一点SpringBoot相关的东西,貌似出去找工作都会被深深地鄙视,不过在我们开...

Java工程师-Distance ⋅ 06/01 ⋅ 0

Spring IOC知识点一网打尽!

前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 单例模式你会几种写法? 工厂模式理解了没有? 在刷Spring书籍的时候花了点时间去学习了单例模式和工...

Java3y ⋅ 05/22 ⋅ 0

IOC/AOP工具 - jBeanBox

jBeanBox是一个微形但功能较齐全的IOC/AOP工具适用于JAVA7+,利用了Java的初始化块实现的Java配置代替XML。jBeanBox采用Apache License 2.0开源协议。 其他一些IOC/AOP框架的问题: 1)Sprin...

yong9981 ⋅ 2016/07/25 ⋅ 14

深入理解Spring源码(一)-IOC容器的定位,载入,注册

前言:Spring源码继承,嵌套层次非常多,读起来非常容易晕,小伙伴们在看文章的时候一定要跟着文章的思路自己去源码里点一点,看一看,并且多看几次。就会越来越清晰。下面开始正题 1.Spring...

Meet相识_bfa5 ⋅ 05/01 ⋅ 0

1 Spring核心:IoC容器的实现

依赖控制反转的实现有很多种方式。在Spring中,IoC容器是实现这个模式的载体, 它可以在对象生成或初始化时直接将数据注入到对象中,也可以通过将对象引用注入到对象数据域中的方式来注入对方...

qq_18150351 ⋅ 04/24 ⋅ 0

Spring IoC & DI

IOC诞生的历史 在没有IoC时,关联不同模块是通过类实例实现的,代码可能是这样子的: 当YourServiceImpl的接口不变时,只需要根据业务需要更换不同的YourService实现类即可。一旦更换实现类时...

classfly ⋅ 06/18 ⋅ 0

Spring源码解析系列之IOC容器(一)

前言 实际上我所有的博客都是原来对原来印象笔记里笔记内容的加工,关于Spring源码自己已经解析了很多遍,但是时间长总是忘记,写一篇博客权当加强记忆,也算再次学习下大师们的设计思想,思...

后厂村老司机 ⋅ 06/02 ⋅ 0

Spring BeanFactory和FactoryBean

Spring BeanFactory和FactoryBean 1、BeanFactory BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的的最基本的接口,也就是 Spring IOC所遵守的最底层和最基本的编程规范...

秋风醉了 ⋅ 04/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Java NIO之字符集

1 字符集和编解码的概念 首先,解释一下什么是字符集。顾名思义,就是字符的集合。它的初衷是把现实世界的符号映射为计算机可以理解的字节。比如我创造一个字符集,叫做sex字符集,就包含两个...

士别三日 ⋅ 36分钟前 ⋅ 0

Spring Bean基础

1、Bean之间引用 <!--如果Bean配置在同一个XML文件中,使用local引用--><ref bean="someBean"/><!--如果Bean配置在不同的XML文件中,使用ref引用--><ref local="someBean"/> 其实两种......

霍淇滨 ⋅ 41分钟前 ⋅ 0

05、基于Consul+Upsync+Nginx实现动态负载均衡

1、Consul环境搭建 下载consul_0.7.5_linux_amd64.zip到/usr/local/src目录 cd /usr/local/srcwget https://releases.hashicorp.com/consul/0.7.5/consul_0.7.5_linux_amd64.zip 解压consu......

北岩 ⋅ 44分钟前 ⋅ 0

Webpack 4 api 了解与使用

webpack 最近升级到了 v4.5+版 01 官方不再支持 node4 以下版本 官方不再支持 node4 以下版本官方不再支持 node4 以下的版本,所以如果你的node版本太低,先开始升级node吧!话说node10 ...

NDweb ⋅ 54分钟前 ⋅ 0

使用nodeJs安装Vue-cli

Vue脚手架就是一个Vue框架开发环境 脚手架的意思是帮你快速开始一个vue的项目,也就是给你一套vue的结构,包含基础的依赖库,只需要 npm install就可以安装,让我们不需要为了编辑或者一些其...

木筏笔歆 ⋅ 今天 ⋅ 0

【微信小程序开发实战】0x00.开发前准备工作

写在开始 本人资深后端码农一枚,近期项目需求,接触到了微信小程序,将学习过程整理成文分享给小伙伴们,由于是边学边整理难免有表述不对的地方,望大家及时指正,感谢。 本人微信号: dream...

dreamans ⋅ 今天 ⋅ 0

linux redis的安装和php7下安装redis扩展

安装redis服务器 (1)下载安装包: $ wget http://download.redis.io/releases/redis-2.8.17.tar.gz (2)编译程序: $ tar xzf redis-2.8.17.tar.gz $ cd redis-2.8.17 $ make $ cd src &&......

concat ⋅ 今天 ⋅ 0

Guava EventBus源码解析

一、EventBus使用场景示例 Guava EventBus是事件发布/订阅框架,采用观察者模式,通过解耦发布者和订阅者简化事件(消息)的传递。这有点像简化版的MQ,除去了Broker,由EventBus托管了订阅&...

SaintTinyBoy ⋅ 今天 ⋅ 0

http怎么做自动跳转https

Apache 版本 如果需要整站跳转,则在网站的配置文件的<Directory>标签内,键入以下内容: RewriteEngine on RewriteCond %{SERVER_PORT} !^443$ RewriteRule ^(.*)?$ https://%{SERVER_NAME......

Helios51 ⋅ 今天 ⋅ 0

Python爬虫,抓取淘宝商品评论内容

作为一个资深吃货,网购各种零食是很频繁的,但是能否在浩瀚的商品库中找到合适的东西,就只能参考评论了!今天给大家分享用python做个抓取淘宝商品评论的小爬虫! 思路 我们就拿“德州扒鸡”...

python玩家 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部