Spring framework(3):IoC(1) IoC 容器&上下文对象

IoC 概述

概念

IoC(Inverse of Control)控制反转是 Spring 容器的内核,AOP、声明式事务等都是基于该概念;
从概念上来说,可以用 DI(Dependency Injection)依赖注入来代替Ioc的理解:让调用类对某一接口的依赖关系由第三方(容器或协作类)注入,以移除调用类对某一接口的依赖;

Ioc 的类型

从注入方法来来看,Ioc主要划分为 3 类: 属性注入,构造函数注入,接口注入
Spring 支持其中的属性注入,构造函数注入(同时还支持派生出来的工厂方法注入);
Spring 对 Ioc 的支持是基于 Java reflect 类反射来实现的;



IoC 容器 


BeanFactory 和 ApplictionConext

Spring 通过配置文件描述 Bean 之间的依赖关系,再由Java的反射功能实例化 Bean,并建立 Bean 之间的依赖关系;
BeanFactory (com.springframework.beans.factory.BeanFactory) IoC 容器:是 Spring 最核心的功能接口,提供了高级 IoC 的配置;


AppliactionContext( com.springframework.context.ApplicationContext)应用上下文 :建立在 BeanFactory 之上,同时实现更多的应用功能,在开发过程中一般更多使用ApplicationConext 作为 IoC 容器对象,因此 ApplictionContext 也被称为 Spring 容器;



※ BeanFactory 主要面向 Spring 框架开发本身,ApplictionContext 面对 Spring 框架应用开发者,几乎所有的场合都会使用 ApplicationContext 而非底层的 BeanFactory;

※ ApplicationContext 和 BeanFactory 在初始化上有一个区别:
BeanFactory 在初始化容器时,不会实例化Bean,直到访问第一个 Bean 时才会实例化该Bean;
ApplicationContext 在初始化上下文的时候会实例化所有单实例的Bean,因此一般初始化时间会比 BeanFactory 更久,以换取之后更快的Bean实例调用速度;

BeanFactory 和 ApplictionContext 常用的API

T getBean(String name,Class<T> requiredType)返回一个指定Bean的示例
Class<T> getType(String name)返回指定名称的Bean的类型
其中 ApplicationContext 的子类 ConfigurableApplication 拓展提供了 refresh() 、close()法,为 ApplictionContext 的具体类提供了刷新、关闭上下文的能力;
以上是与Bean使用相关的API ,完整 API 见官方完整的 API 文档;


ApplictionContext 的常用实现类

ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext

这两者主要用于加载使用 XML ,注解方式配置的 Bean,前者用于加载类路径下的配置文件,后者则使用系统路径加载配置文件;
 
//使用 ClassPathXmlApplicationContext 加载指定Bean,该Bean的配置文件路径为 myporject/src/main/resources/site/assad/demo/beans.xml
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("site/assad/demo/beans.xml");
Car car = ctx.getBean("car1",Car.class);
//也可以加载一组指定的xml配置文件,Spring会自动整合为一个配置文件;
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("conf/bean1.xml","conf/bean2.xml");

AnnotationConfigApplication

该具体类用于加载基于JavaConfig类配置的Bean
 
ApplictionContext ctx = new AnnnoConfigAppliction(Bean.class);
Car car = ctx.getBean("car1",Car.class);

GenericGroovyApplicationContext

该具体类用于加载基于Groovy DSL配置的Bean
 
ApplictionContext ctx = new GenericGroovyApplicationContext("classpath:site/assad/demo/groovy-beans.groovy");
Car car = ctx.getBean("car1",Car.class);




WebApplicationContext 体系


WebApplicationContext 是为 Web 应用准备的 ApplicationContext 实现类,它允许从相对于 Web 根目录的路径中装载配置文件以完成初始化工作,同时可以获取 ServletContext 的引用,将整个 Web 应用上下文对象作为属性放到 ServletContext 之中,以便 Web 应用环境可以访问 Spring 应用的上下文

在非 Web 环境下,Bean 只有 singleton , prototype 2种作用域,WebApplictionContext 为 Bean 增加了3种作用域:request,session,global session ;
同时 WebApplictionContext 定义一个常量 ROOT_WEB_APPLICTION_CONTEXT_ATTRIBUTE 用于在上下文启动时,在 ServletContext 的属性列表中存放 WebApplictionContext 实例, 如下:
 
WebApplicationContext wac = (WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICTION_CONTEXT_ATTRIBUTE);

ConfigurableWebApplicationContext 是 WebApplicationContext 的工具子类 ConfigurableApplicationContext 允许通过配置的方式实例化 WebApplicationContext ,其定义了2个重要的方法:
setServletContext(ServletContext servletContext)为Spring设置Web上下文
setConfigLocations(String[] configLocations)设置Spring 配置文件地址,一般 破日子文件是相对于 Web 根目录的,如:/WEB-INF/assad-dao.xml,/WEB-INF/assad-service.xml 等;也可以使用带资源类型前缀的地址,如:classpath:site/assad/beans.xml

WebApplicationConetxt 的初始化配置
WebApplicationConetxt 的初始化需要 ServletContext 实例,即必须在拥有 Web 容器的前提下才能启动该上下文;
可以在  web.xml 配置自启动的 Servlet 或 ServletContextListener(Web容器监听器)来启动 WebApplicationConetxt, Spring 分别提供了以下2个类用于实现这2个功能:
  • org.springframework.web.context.ContextLoaderServlet
  • org.springframework.web.context.ContextLoaderListener

以详解多种Bean装配方式的 WebApplicationContext 初始化:

通过xml配置Bean的初始化

① 通过 ContextLoaderListener 启动 
 
<web-app>
....
    <!--指定配置文件-->
     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/assad-dao.xml,/WEB-INF/assad-dao.xml</param-value>
    </context-param>
    .....
    <!--声明 Web 容器监听器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>
① 通过 ContextLoaderServlet 启动 
 
<web-app>
....
    <!--指定配置文件-->
     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/assad-dao.xml,/WEB-INF/assad-dao.xml</param-value>
    </context-param>
    .....
    <!--声明自启动的Servlet-->
    <servlet>
        <servlet-name>springContextLoaderServlet</servlet-name>
        <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
</web-app>

通过JavaConfig配置Bean的初始化

对于使用标注 @Configuration 的Java 类提供配置信息,则 web.xml 需要按照类似以下的方式配置(以下只演示ContextLoaderListener 方式,另一种方式类似):
 
<web-app>
....
   <!--让Spring使用 AnnotationConfigWebApplication 而非 XmlWebApplicationContext启动容器-->
   <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
   </context-param>
    <!--指定标注了 @Configuration 的配置类,多个类可以使用逗号或空格分开-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>site.assad.AppConfig1,site.assad.AppConfig2</param-value>
    </context-param>
    .......
    <!--声明 Web 容器监听器,ContextLoaderListener将使用上配置使用的AnnotationConfigWebApplication根据contextConfigLocation启动Spring容器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

通过 Groovy 配置Bean的初始化

以下只演示ContextLoaderListener 方式,另一种方式类似:
 
<web-app>
....
   <!--让Spring使用 AnnotationConfigWebApplication 而非 XmlWebApplicationContext启动容器-->
   <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.GroovyWebApplicationContext
        </param-value>
   </context-param>
    <!--指定Groovy配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>Classpath*:conf/spring-mvc.groovy</param-value>
    </context-param>
    .......
    <!--声明 Web 容器监听器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

Log4J 引擎的配置

WebApplicationContext 需要使用日志功能,可以将 Log4J 的配置文件放置在类路径 WEB-INF/classes 下,此时 Log4J 引擎可以自动启动,如果 Log4J 配置文件位于其他位置,可以按照以下的方式配置(以ContextLoaderServlet的方式示例):
 
<web-app>
....
     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/assad-dao.xml,/WEB-INF/assad-dao.xml</param-value>
    </context-param>
    ......
    <!--指定Log4J配置文件的位置-->
     <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j2.xml</param-value>
    </context-param>
    <!--装载Log4J配置文件的自启动Servlet-->
     <servlet>
        <servlet-name>log4jConfigServlet</servlet-name>
        <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    ......
     <servlet>
        <servlet-name>springContextLoaderServlet</servlet-name>
        <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
</web-app>
注意必须保证在装载Spring配置文件之前先装载Log4J配置文件信息

















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值