`

Spring学习之一:Ioc容器加单学习+applicationcontext

  
阅读更多
最近工作比较轻松,自主学习的时间很多,对于前段时间在网上学习,没有方向没有目的 感到遗憾不已,总是觉得要学习新的技术,却忘记了之前学习的东西都还没有巩固.还好,现在醒悟不算太晚.要学习的东西真的很多.而现在,终于想开始学习Spring了


Ioc容器学习 + applicationcontext

Ioc 控制反转,也叫依赖注入.先讲下控制反转的意思,控制是指容器控制程序的关系,而不是传统的用代码来控制程序.反转,即这种代码控制程序转移为容器控制程序.
依赖注入:组件之间的依赖关系由容器在运行期间完成,由容器动态的管理组件之间的依赖关系.
传统的方式:需要一个对象就自己 New()一个对象来使用.而现在直接从容器中获取就ok了.
 
Spring 的Ioc容器,其实可以理解我BeanFactory,通过BeanFactory来实例化,配置和管理对象.BeanFactory是一个接口,常见的实现有XmlBeanFactory(使用Xml定义容器中的bean),AbstractBeanFactory,DefaultListableBeanFactory.
另外Resource接口用来抽象bean定义数据,XmlBeanDefinitionReader用于对xml定义bean的文件的解析。
看一下BeanFactory的源码:

    public   interface  BeanFactory {  
     
         //这里是对FactoryBean的转义定义,因为如果使用 bean的名字检索FactoryBean得到的对象是工厂生成的对象,  
         //如果需要得到工厂本身,需要转义         
        String FACTORY_BEAN_PREFIX =  "&" ;  
     
     
         //这里根据bean的名字,在IOC容器中得到bean实 例,这个IOC容器就是一个大的抽象工厂。  
        Object getBean(String name)  throws  BeansException;  
     
         //这里根据bean的名字和Class类型来得到bean实 例,和上面的方法不同在于它会抛出异常:如果根据名字取得的bean实例的Class类型和需要的不同的话。  
        Object getBean(String name, Class requiredType)  throws  BeansException;  
     
         //这里提供对bean的检索,看看是否在IOC容器有这个名 字的bean  
         boolean  containsBean(String name);  
     
         //这里根据bean名字得到bean实例,并同时判断这个 bean是不是单件  
         boolean  isSingleton(String name)  throws  NoSuchBeanDefinitionException;  
     
         //这里对得到bean实例的Class类型  
        Class getType(String name)  throws  NoSuchBeanDefinitionException;  
     
         //这里得到bean的别名,如果根据别名检索,那么其原名也 会被检索出来  
        String[] getAliases(String name);  
     
    } 


接下来简单的给大家看一下Ioc容器的创建过程:

 1. 创建IOC配置文件的抽象资源
   2. 创建一个BeanFactory
   3. 把读取配置信息的BeanDefinitionReader,这里是XmlBeanDefinitionReader配置给BeanFactory
   4. 从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成,这样完成整个载入bean定义的过程。我们的 IoC容器就建立起来了。在BeanFactory的源代码中我们可以看到.
如下代码:
ClassPathResource res =  new  ClassPathResource( "beans.xml" );  
DefaultListableBeanFactory factory =  new  DefaultListableBeanFactory();  
XmlBeanDefinitionReader reader =  new  XmlBeanDefinitionReader(factory);  
reader.loadBeanDefinitions(res);

applicationcontext
先说几个applicationcontext的几个特点,
1,applicationcontext(Spring的上下文) 是在beanfactory的基础上扩展而来的,除了具备BeanFactory的全部能力,还具有其他的新的功能。
2,applicationcontext扩展了MessageSource
3,applicationcontext 支持ResourceLoader和Resource,可以从不同的地方访问bean资源
4,applicationcontext允许上下文嵌套,通过保持父上下文来维持一个上下文体系,这个体系在我们的web容器分析中可以看到.
BeanFactory 和 ApplicationContext在不同的使用层面上代表了Spring提供Ioc容器服务.
由于applicationcontext比BeanFactory更加好用,用的更多的当然就是它了。
ApplicationContext提供Ioc容器的主要接口,在其体系中有许多的抽象子类。例如常见的:AbstractApplicationContext,FileSystemXmlApplicationContext,ClassPathXmlApplicationContext.

接下来重点说一下web开发中获取Spring的AplicationContext的三种方式:

首先要看一下源码,了解一下ApplicationContext的存储.
web.xml中的配置:
    <listener> 
         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
      </listener> 
配置了监听器ContextLoaderListener,追踪一下ContextLoaderListener

public class ContextLoaderListener implements ServletContextListener { 
 
    private ContextLoader contextLoader; 
 
    /**
     * Initialize the root web application context.
     */ 
    public void contextInitialized(ServletContextEvent event) { 
        this.contextLoader = createContextLoader(); 
        this.contextLoader.
    initWebApplicationContext(event.getServletContext()); 
    }

再看一下: initWebApplicationContext方法,

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) 
            throws IllegalStateException, BeansException { 
 
        //从ServletContext中查找,是否存在以//WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE为Key的值

    if(servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null){ 
        throw new IllegalStateException( 
                "Cannot initialize context because there is already a root application context present - " + 
                "check whether you have multiple ContextLoader* definitions in your web.xml!"); 
    } 
     
             
    try { 
        // Determine parent for root web application context, if any. 
        ApplicationContext parent = loadParentContext(servletContext); 
     
        // it is available on ServletContext shutdown. 
        this.context = createWebApplicationContext(servletContext, parent); 
        //将ApplicationContext放入ServletContext中,其key为//WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);</span></span> 
            //将ApplicationContext放入ContextLoader的全局静态常量Map中,其中key
//为:Thread.currentThread().getContextClassLoader()即当前线程类加载器
        currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this.context); 
     
        return this.context; 
    } 

上面的代码表明,ContextLoaderListener实现了ServeletContextListenet,在ServletContext初始化的时候,会进行Spring的初始化。同时Spring初始化之后,将ApplicationContext存到在了两个地方,意味着我们有两种方式可以获取ApplicationContext。
第一种:
注意:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

即为 "org.springframework.web.context.WebApplicationContext.ROOT"
那就可以这样获得ApplicationContext:
request.getSession().getServletContext().getAttribute("org.springframework.web.context.WebApplicationContext.ROOT") ,其实Spring已经给了我们接口,
使用spring的工具类来获取:

ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
ac1.getBean("beanId");
ac2.getBean("beanId");
说明:
这种方式适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后在通过它获取需要的类实例。


其中 servletContext sc 可以具体 换成 servlet.getServletContext()或者 this.getServletContext() 或者 request.getSession().getServletContext(); 另外,由于spring是注入的对象放在ServletContext中的,所以可以直接在ServletContext取出 WebApplicationContext 对象: WebApplicationContext webApplicationContext = (WebApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);


第二种方法:
前面说到Spring初始化的时候,将ApplicationContext还存了一份到ContextLoader的Map里面,然而这个Map是私有的,我们直接拿不到的呢。
当然spring也提供了方法的:
    <span style="color: #000000;">public static</span> WebApplicationContext getCurrentWebApplicationContext() { 
            return (WebApplicationContext) currentContextPerThread.get(Thread.currentThread().getContextClassLoader()); 
        } 

第三种方式:
借用ApplicationContextAware,ApplicationContext的帮助类能够自动装载ApplicationContext,只要你将某个类实现这个接口,并将这个实现类在Spring配置文件中进行配置,Spring会自动帮你进行注

入 ApplicationContext.ApplicationContextAware的代码结构如下:

    public interface ApplicationContextAware { 
         
            void setApplicationContext(ApplicationContext applicationContext) throws BeansException; 
     
    } 



关于spring中的ApplicationContext可在另外一篇博客中看。

分享到:
评论

相关推荐

    Spring源代码解析(一):IOC容器.doc

    在Spring源代码解析的第一部分,我们将聚焦于IOC容器,特别是BeanFactory接口,它是所有Spring容器的基础。 BeanFactory接口是Spring的基石,它定义了基本的容器操作,如获取Bean、检查Bean是否存在、确定Bean的...

    Spring源代码解析(二):IoC容器在Web容器中的启动.doc

    当我们在Web环境中运行Spring应用时,IoC容器需要在Web容器(如Tomcat、Jetty等)中启动并运行。这个过程涉及到一系列的初始化步骤,确保Spring能够正确地与Web容器集成。 首先,`WebApplicationContext`是`...

    Spring基础:IoC容器(2)

    至于“工具”标签,可能意味着博主分享了如何在实际项目中使用Spring IoC容器,或者介绍了一些与之相关的工具和技巧,比如使用Maven进行构建和管理依赖。 在文件名称“maventest06”中,我们可以推测这是一个Maven...

    Spring中IoC优点与缺点解析

    IoC(Inversion of Control)是 Spring 框架中的一种设计模式,它的主要思想是将对象的创建和管理交给容器,从而解耦合对象之间的依赖关系。今天,我们将详细解析 IoC 的优点和缺点。 优点 1. 简化对象的创建:IoC ...

    Spring2.5.6源代码分析(一):IOC容器

    Spring的IoC容器主要由两部分组成:Bean工厂(BeanFactory)和应用上下文(ApplicationContext)。Bean工厂是最基本的容器,它实现了对bean的管理和配置。而ApplicationContext则在Bean工厂的基础上增加了更多的企业...

    Spring IOC容器实现分析.pdf 下载

    本文将深入剖析Spring的IOC容器,理解其工作原理和重要功能,以帮助开发者更好地利用这一强大的工具。 一、IOC容器的概念 IOC,即控制反转,是面向对象编程中的一个设计原则,它的主要思想是将对象的创建和管理权...

    Spring实现原理及IoC容器的优点

    本篇文章将深入探讨Spring实现原理,阐述IoC容器的优点,并指导如何在Eclipse中创建一个Spring的Web应用。 首先,让我们理解Spring的核心——IoC容器。IoC是一种设计模式,它改变了对象获取依赖的方式。在传统的...

    Spring的IoC容器初始化源码解析

    ### Spring的IoC容器初始化源码解析 #### 一、Spring框架的核心——IoC容器 Spring框架是一个开源的轻量级Java开发框架,其核心功能...对于希望深入学习Spring框架的开发者来说,理解IoC容器的工作原理是非常重要的。

    Spring的IoC容器

    **Spring的IoC容器详解** Spring框架的核心特性之一是依赖注入(Dependency Injection,简称DI),而实现这一特性的核心组件就是IoC(Inversion of Control)容器。IoC容器是Spring框架的心脏,它负责管理对象的...

    Java-Spring-SpringIoC容器-SpringIoC的学习

    在Java Spring框架中,Spring IoC(Inversion of Control,控制反转)是核心特性之一,它使得应用程序的组件之间的依赖关系不再由代码直接管理,而是交由Spring IoC容器负责。这种设计模式降低了代码间的耦合,提高...

    模拟Spring的IoC容器实现注解自动装配

    而注解自动装配(Autowired)是Spring IoC容器的一种高级特性,它允许我们通过注解来声明对象之间的依赖,无需手动编写XML配置。现在,我们将深入探讨如何模拟Spring的IoC容器实现注解自动装配。 首先,我们需要...

    Spring IoC容器实现的结构分析

    总之,Spring IoC容器的实现是一个复杂而精巧的设计,它通过一系列组件协同工作,实现了对象的创建、装配和管理,为开发者提供了强大的依赖注入功能。无论是简单的应用还是复杂的分布式系统,Spring IoC容器都能有效...

    Spring源码分析_Spring_IOC

    ### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...

    Spring核心学习IOC部分

    本学习资料主要聚焦于Spring的IOC容器,特别是从最基本的BeanFactory开始,逐步深入理解如何构建一个类似Spring功能的系统。 首先,BeanFactory是Spring的最基本容器,它负责管理对象(也称为Bean)。BeanFactory...

    09 Spring IoC容器ApplicationContext如何实现国际化慕课专栏1

    在Spring框架中,ApplicationContext是IoC容器的核心,它不仅负责管理Bean,还提供了实现国际化(i18n)的功能。国际化使应用程序能够适应不同语言和地区的用户,无需修改代码即可提供多语言支持。Spring通过实现...

    实验一 Springioc基本操作.docx

    SpringIOC是Spring Framework中的核心组件之一,负责管理应用程序中的对象、依赖关系和生命周期。 在 Spring IOC 中,对象的创建和管理是通过 BeanFactory 或 ApplicationContext 实现的。BeanFactory 是 Spring ...

Global site tag (gtag.js) - Google Analytics