spring IOC容器实现探讨

   spring IOC容器的实现,一开始我被复杂的接口和类所掩埋,看不清整体的思路和设计,踟蹰于代码丛林中,摸不清前进的方向。一开始我就决定只研读以xml文件做配置文件的XmlFactoryBean的具体实现为主要目标,渐渐地有了点感觉,用UML把spring中的bean工厂体系展现出来之后就更清晰了,让你不得不感叹设计的精巧和复杂。本文只是我个人对spring IOC实现的理解,如有错误,请不吝赐教,谢谢。
    首先,需要理解的是spring容器中bean的生命周期,《spring in action》中的那张图是最好的解释,结合这张图和源码来解读spring中IOC的实现将非常容易理解。这张图完整展示了spring容器中一个bean从创建到销毁的整个生命周期。
   
1. 容器寻找Bean的定义信息并且将其实例化。
2.受用依赖注入,Spring按照Bean定义信息配置Bean的所有属性。
3.如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。
4.如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。
5.如果BeanPostProcessor和Bean关联,那么它们的postProcessBeforeInitialzation()方法将被调用。
6.如果Bean指定了init-method方法,它将被调用。
7.最后,如果有BeanPsotProcessor和Bean关联,那么它们的postProcessAfterInitialization()方法将被调用。
    到这个时候,Bean已经可以被应用系统使用了,并且将被保留在Bean Factory中知道它不再需要。有两种方法可以把它从Bean Factory中删除掉。
1.如果Bean实现了DisposableBean接口,destory()方法被调用。
2.如果指定了订制的销毁方法,就调用这个方法。
   
    下面我们将会看到,这些bean创建销毁的每个阶段是如何在源码中实现的。
    再看看spring中bean工厂的完整体系,比较复杂,不过我们只需要关注其中的几个核心工厂。
    
    (看不清楚,请下载图片来看,比较清晰)
    这些工厂类没有在同一个包内,分布在org.springframework.beans以及它的子包内,把它们放在一起就看的比较清楚了。我们需要关注的是这么两个类:org.springframework.beans.factory.support.AbstractBeanFactory
org.springframework.beans.factory.support.DefaultListableBeanFactory
以及接口:
org.springframework.beans.factory.support.BeanDefinitionRegistry

    AbstractBeanFactory作为BeanFactory接口的抽象实现类,是其他工厂类的父类,提供了bean的singlton缓存、singleton/prototype的决定、bean的别名以及bean和它的子类bean的定义合并(bean definition merging for child bean definitions)和销毁。这里有3个重载的getBean方法(实现BeanFactory定义的getBean方法),我们关注下最主要的这个方法:

public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
        String beanName = transformedBeanName(name);
        Object bean = null;

        // Eagerly check singleton cache for manually registered singletons.
        Object sharedInstance = null;
        //从单例缓存中获取
        synchronized (this.singletonCache) {
            sharedInstance = this.singletonCache.get(beanName);
        }
        if (sharedInstance != null) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
            }
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            bean = getObjectForSharedInstance(name, sharedInstance);
        }

        else {
            // Fail if we're already creating this singleton instance:
            // We're assumably within a circular reference.
            if (isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            //检测bean是否定义在父工厂
            if (getParentBeanFactory() != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                if (getParentBeanFactory() instanceof AbstractBeanFactory) {
                    // Delegation to parent with args only possible for AbstractBeanFactory.
                    return ((AbstractBeanFactory) getParentBeanFactory()).getBean(name, requiredType, args);
                }
                else if (args == null) {
                    // No args -> delegate to standard getBean method.
                    return getParentBeanFactory().getBean(name, requiredType);
                }
                else {
                    throw new NoSuchBeanDefinitionException(beanName,
                            "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments");
                }
            }

            //获取BeanDefinition
            RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
            checkMergedBeanDefinition(mergedBeanDefinition, beanName, requiredType, args);

            // Create bean instance.
            //创建bean,如果为为singleton
            if (mergedBeanDefinition.isSingleton()) {
                synchronized (this.singletonCache) {
                    // Re-check singleton cache within synchronized block.
                    sharedInstance = this.singletonCache.get(beanName);
                    if (sharedInstance == null) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                        }
                        this.currentlyInCreation.add(beanName);
                        try {
                            sharedInstance = createBean(beanName, mergedBeanDefinition, args);
                            //加进单例缓存
                            addSingleton(beanName, sharedInstance);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroyDisposableBean(beanName);
                            throw ex;
                        }
                        finally {
                            this.currentlyInCreation.remove(beanName);
                        }
                    }
                }
                bean = getObjectForSharedInstance(name, sharedInstance);
            }
            //如果是prototype
            else {
                // It's a prototype -> create a new instance.
                bean = createBean(beanName, mergedBeanDefinition, args);
            }
        }

        // Check if required type matches the type of the actual bean instance.
        if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
        return bean;
    }

    当你调用getBean获取一个bean的时候,spring首先查找单例缓存中是否已经有这个bean,有的话直接返回(首先会判断是否已经创建),如果没有,spring就开始创建这个bean:首先获取bean的定义(BeanDefinition),检测bean是否定义在父工厂中,有的话调用父工厂的getBean方法;没有就检测bean是singleton还是prototype,如果是singleton就是创建bean并加入缓存以便下次直接调用,如果是prototype,就在每次调用时重新创建一个bean实例。注意createBean(beanName, mergedBeanDefinition, args); 这个方法,这是创建bean的核心方法,并且是一个abstract方法,将被子类实现。
    看看是如何获取bean的定义的,

protected RootBeanDefinition getMergedBeanDefinition(String name, boolean includingAncestors)
        throws BeansException {

        String beanName = transformedBeanName(name);

        // Efficiently check whether bean definition exists in this factory.
        if (includingAncestors && !containsBeanDefinition(beanName) &&
                getParentBeanFactory() instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName, true);
        }

        // Resolve merged bean definition locally.
        return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    }

    调用重载的getMergedBeanDefinition合并父工厂和子工厂中的bean定义,注意getBeanDefinition(beanName),这是一个抽象方法,延迟到子类实现以便提供获取bean定义的具体方法,这个方法和 createBean 一样都是template method模式的应用。看看它们的定义:

protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;

protected abstract Object createBean(
            String beanName, RootBeanDefinition mergedBeanDefinition, Object[] args) throws BeanCreationException;

 
    基本了解了AbstractBeanFactory 后,我们来看看它的子类的AbstractAutowireCapableBeanFactory ,这个类实现了createBean() ,在这个方法中我们将看到与上面bean的生命周期图对应的bean的创建过程,英文注释已经非常清楚:

protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition, Object[] args)
            throws BeanCreationException {

        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean '" + beanName +
                    "' with merged definition [" + mergedBeanDefinition + "]");
        }

        Object bean = null;

        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        if (mergedBeanDefinition.hasBeanClass()) {
            bean = applyBeanPostProcessorsBeforeInstantiation(mergedBeanDefinition.getBeanClass(), beanName);
            if (bean != null) {
                return bean;
            }
        }

        // Guarantee initialization of beans that the current one depends on.
        if (mergedBeanDefinition.getDependsOn() != null) {
            for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) {
                getBean(mergedBeanDefinition.getDependsOn()[i]);
            }
        }

        BeanWrapper instanceWrapper = null;
        Object originalBean = null;
        String errorMessage = null;

        try {
            // Instantiate the bean.
            errorMessage = "Instantiation of bean failed";

            if (mergedBeanDefinition.getFactoryMethodName() != null)  {
                instanceWrapper = instantiateUsingFactoryMethod(beanName, mergedBeanDefinition, args);
            }
            else if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                    mergedBeanDefinition.hasConstructorArgumentValues() )  {
                instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
            }
            else {
                // No special handling: simply use no-arg constructor.
                instanceWrapper = instantiateBean(beanName, mergedBeanDefinition);
            }
            bean = instanceWrapper.getWrappedInstance();

            // Eagerly cache singletons to be able to resolve circular references
            // even when triggered by lifecycle interfaces like BeanFactoryAware.
            if (isAllowCircularReferences() && isSingletonCurrentlyInCreation(beanName)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Eagerly caching bean with name '" + beanName +
                            "' to allow for resolving potential circular references");
                }
                addSingleton(beanName, bean);
            }

            // Initialize the bean instance.
            errorMessage = "Initialization of bean failed";
            populateBean(beanName, mergedBeanDefinition, instanceWrapper);

            if (bean instanceof BeanNameAware) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Invoking setBeanName on BeanNameAware bean '" + beanName + "'");
                }
                ((BeanNameAware) bean).setBeanName(beanName);
            }

            if (bean instanceof BeanFactoryAware) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Invoking setBeanFactory on BeanFactoryAware bean '" + beanName + "'");
                }
                ((BeanFactoryAware) bean).setBeanFactory(this);
            }

            originalBean = bean;
            bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
            invokeInitMethods(beanName, bean, mergedBeanDefinition);
            bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
        }
        catch (BeanCreationException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mergedBeanDefinition.getResourceDescription(), beanName, errorMessage, ex);
        }

        // Register bean as disposable, and also as dependent on specified "dependsOn" beans.
        registerDisposableBeanIfNecessary(beanName, originalBean, mergedBeanDefinition);

        return bean;
    }

    通过instanceof操作符来判断bean是否实现了用于生命周期回调的接口,然后调用相应的回调方法,可以看到spring充分实践了针对接口编程的原则,虽然很夸张的一个方法一个接口的地步,不过这些接口也是作为mark interface用于标记回调。结合上面的生命周期图看这段代码将很好理解。有了bean的创建方法,那么如何获取bean在配置文件中的定义信息呢?也就是在哪里实现了 getBeanDefinition方法呢?答案就在AbstractAutowireCapableBeanFactory 的子类DefaultListableBeanFactory中。

    DefaultListableBeanFactory 不仅继承了AbstractAutowireCapableBeanFactory ,还实现了BeanDefinitionRegistry和ConfigurableListableBeanFactory接口。其中ConfigurableListableBeanFactory接口是定义了分析和修改bean定义信息的回调方法,暂时不去管它。看看BeanDefinitionRegistry接口:

public interface BeanDefinitionRegistry {
  int getBeanDefinitionCount();
  String[] getBeanDefinitionNames();
  BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
  String[] getAliases(String beanName) throws NoSuchBeanDefinitionException;
  void registerAlias(String beanName, String alias) throws BeansException;
  void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeansException;
  ......
}

一系列用于获取bean定义信息的方法,这个接口我们将在后面的代码中看到,作为一个mark inteface。注意咯,这个接口中非常关键的一个方法就是registerBeanDefinition,这个方法用于向bean工厂注册解析的每个bean定义,我们将在xml文件的解析的环节看到调用这个方法注册bean定义信息。

    DefaultListableBeanFactory实现了BeanDefinitionRegistry  接口,可以看到它实现了关键的registerBeanDefinition用于将bean的定义注册到工厂类中,其中维护了一个Map用于存储bean的定义信息:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {

        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "Bean definition must not be null");

        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }

        Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
        if (oldBeanDefinition != null) {
            if (!isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                        "': there's already [" + oldBeanDefinition + "] bound");
            }
            else {
                if (logger.isInfoEnabled()) {
                    logger.info("Overriding bean definition for bean '" + beanName +
                            "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            }
        }
        else {
            this.beanDefinitionNames.add(beanName);
        }
        this.beanDefinitionMap.put(beanName, beanDefinition);

        // Remove corresponding bean from singleton cache, if any.
        // Shouldn't usually be necessary, rather just meant for overriding
        // a context's default beans (e.g. the default StaticMessageSource
        // in a StaticApplicationContext).
        removeSingleton(beanName);
    }

    beanDefinitionMap就是我们存储工厂类中注册的bean的信息,用bean name做为key:

/** Map of bean definition objects, keyed by bean name */
    private final Map beanDefinitionMap = new HashMap();

 
    DefaultListableBeanFactory 重写了

protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;

模板方法用于提供bean定义信息给getBean方法用于创建bean实例。getBeanDefinition的从beanDefinitionMap 查找bean定义即可:

public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        BeanDefinition bd = (BeanDefinition) this.beanDefinitionMap.get(beanName);
        if (bd == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("No bean named '" + beanName + "' found in " + toString());
            }
            throw new NoSuchBeanDefinitionException(beanName);
        }
        return bd;
    }

    看到了这里是不是觉的有点糊涂,我还是建议有兴趣地找来spring1.2的源码来看看就很清晰了,充分利用eclipse的F3跳转结合上面的那张UML图。
    OK,有了注册bean定义信息的方法(registerBeanDefinition),有了获取bean定义信息的方法(getBeanDefinition ),有了创建bean的方法(createBean),那么在哪里调用这些方法呢?createBean我们已经知道是在BeanFactory的getBean方法时调用,getBeanDefinition 又是在creatBean时调用用于获取bean的定义信息,那么注册bean定义信息的方法肯定是在xml文件解析阶段被调用。
   XmlBeanFactory继承DefaultListableBeanFactory ,没有定义新的方法,只是有两个重载的构造函数:
  

public class XmlBeanFactory extends DefaultListableBeanFactory {
  private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
  public XmlBeanFactory(Resource resource) throws BeansException {
        this(resource, null);
    }
  public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
        super(parentBeanFactory);
        this.reader.loadBeanDefinitions(resource);
    }
}

    初始化XmlBeanFactory时调用XmlBeanDefinitionReader读取xml配置文件,而XmlBeanDefinitionReader的loadBeanDefinitions方法,载入xml文件并且调用XmlBeanDefinitionParser 解析xml文件同时注册bean定义信息到bean工厂,这几个类的协作以及它们继承体系也非常清晰,在此不再详述(累啊),XmlBeanDefinitionParser是一个接口,具体的实现类是org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser,我们关注的就是它是怎么注册bean信息到bean工厂的:

protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException {

    
    if (IMPORT_ELEMENT.equals(node.getNodeName())) {
                    importBeanDefinitionResource(ele);
                }
                else if (ALIAS_ELEMENT.equals(node.getNodeName())) {
                    String name = ele.getAttribute(NAME_ATTRIBUTE);
                    String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
                    this.beanDefinitionReader.getBeanFactory().registerAlias(name, alias);
                }
                else if (BEAN_ELEMENT.equals(node.getNodeName())) {
                    beanDefinitionCount++;
                    BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false);
                    //关键代码,调用工具类将bean定义注册到beanFactory
                    BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory());
                }
   
}

工具类BeanDefinitionReaderUtils中的注册方法:

    public static void registerBeanDefinition(
            BeanDefinitionHolder bdHolder, BeanDefinitionRegistry beanFactory) throws BeansException {

        // Register bean definition under primary name.,注册bean
        beanFactory.registerBeanDefinition(bdHolder.getBeanName(), bdHolder.getBeanDefinition());

        // Register aliases for bean name, if any.,注册别名
        if (bdHolder.getAliases() != null) {
            for (int i = 0; i < bdHolder.getAliases().length; i++) {
                beanFactory.registerAlias(bdHolder.getBeanName(), bdHolder.getAliases()[i]);
            }
        }
    }

   注意这里的beanFactory是BeanDefinitionRegistry类型 ,DefaultListableBeanFactory实现了这个接口。
    更多内容,比如spring是怎么把bean的属性注入的?答案在BeanWrapperImpl中的一系列setPropertyXXX方法。BeanFactory是如何实例化bean的呢?具体展开请看org.springframework.beans.factory.support.InstantiationStrategy 接口,一个典型的策略模式的应用,两个实现类:SimpleInstantiationStrategy和CglibSubclassingInstantiationStrategy。我们知道spring有3种注入方式:setter、构造函数以及Method Inject。这里的CglibSubclassingInstantiationStrategy使用cglib库用于实现method inject。这样一篇小文容不下这么多内容,还是有兴趣的自己找源码读读。

    写到这里,我对自己的文字表达能力产生怀疑,我能不能把这些所有的信息都说清楚呢?感觉很不满意,将就吧,也算是自己的学习总结。
    读spring源码这段时间,最深的几点体会:
1)单元测试非常重要,充分感受到了单元测试作为项目文档的优势。看不懂一个类,找到这个类的测试类就OK!
2)针对接口编程的原则,spring处处体现了这个原则,繁多的接口带来的是松耦合、高内聚并且易于扩展的架构,但也带来了一定的理解难度。作为通用型框架也许需要这么考虑,在实际项目中的取舍还是要自己把握。
3)设计模式的使用,spring中应用了很多模式,比如template method,比如strategy和factory method、visitor、singleton等,简直是一本模式实践的良好教材。

文章转自庄周梦蝶  ,原文发布时间5.17

时间: 2025-01-02 06:06:58

spring IOC容器实现探讨的相关文章

《Spring攻略(第2版)》——1.2 配置Spring IoC容器中的Bean

1.2 配置Spring IoC容器中的Bean 1.2.1 问题 Spring提供了一个强大的IoC容器来管理组成应用的bean.为了利用容器服务,你必须配置运行于Spring IoC容器中的Bean. 1.2.2 解决方案 你可以通过XML文件.属性文件.注释甚至API来配置Spring IoC容器中的Bean. Spring允许你在一个或者多个bean配置文件中配置bean.对于简单的应用程序,可以在单个配置文件中集中配置bean.但是对于有许多bean的大型应用,你应该根据其功能(例如控

《Spring攻略(第2版)》——第1章 Spring简介 1.1实例化Spring IoC容器

第1章 Spring简介 在本章中,你将参加关于Spring.核心容器以及容器所提供的一些全局可用设施的一个速成班(或者一次复习),你还将了解Spring XML配置格式,以及注释驱动的支持.本章将带给你应付本书余下部分中引入的概念所需要的知识.你将学习Spring IoC容器中的基本组件配置.在Spring框架的核心部分,IoC容器的设计具有高度的适应性和可配置性,提供了使你的组件配置尽可能简单的一组工具.你能够很简单地设置运行于Spring IoC容器中的组件. 在Spring中,组件也被称

Spring IOC容器源码浅析

控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心.      控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找.依赖注入应用比较广泛.      将控制权从具体的对象手中交给平台或者是框架. BeanFactory是基本的功能接口 public interface BeanFactory { //这里是对FactoryBean的转义定

Spring源代码解析(二):IOC容器在web容器中的启动

以下引用自博客:http://jiwenke-spring.blogspot.com/ 上面我们分析了IOC容器本身的实现,下面我们看看在典型的web环境中,Spring IOC 容器是怎样被载入和起作用的. 简单的说,在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对 应的建立起一个IOC容器的体系.其中,首先需要建立的是根上下文,这个上下文持有的 对象可以有业务对象,数据存取对象,资源,事物管理器等各种中间层对象.在这个上下 文的基础上,和web MV

《Spring技术内幕》——2.4节IoC容器的依赖注入

2.4 IoC容器的依赖注入 上面对IoC容器的初始化过程进行了详细的分析,这个初始化过程完成的主要工作是在IoC容器中建立BeanDefinition数据映射.在此过程中并没有看到IoC容器对Bean依赖关系进行注入,接下来分析一下IoC容器是怎样对Bean的依赖关系进行注入的. 假设当前IoC容器已经载入了用户定义的Bean信息,开始分析依赖注入的原理.首先,注意到依赖注入的过程是用户第一次向IoC容器索要Bean时触发的,当然也有例外,也就是我们可以在BeanDefinition信息中通过

浅析Java的Spring框架中IOC容器容器的应用_java

Spring容器是Spring框架的核心.容器将创建对象,它们连接在一起,配置它们,并从创建到销毁管理他们的整个生命周期.在Spring容器使用依赖注入(DI)来管理组成应用程序的组件.这些对象被称为Spring Beans. 容器获得其上的哪些对象进行实例化,配置和组装通过阅读提供的配置元数据的说明.配置元数据可以通过XML,Java注释或Java代码来表示.下面的图是Spring如何工作的高层次图. Spring IoC容器是利用Java的POJO类和配置元数据的产生完全配置和可执行的系统或

《Spring技术内幕》——2.2节IoC容器系列的设计与实现:BeanFactory和ApplicationContext

2.2 IoC容器系列的设计与实现:BeanFactory和ApplicationContext在Spring IoC容器的设计中,我们可以看到两个主要的容器系列,一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的最基本功能:另一个是ApplicationContext应用上下文,它作为容器的高级形态而存在.应用上下文在简单容器的基础上,增加了许多面向框架的特性,同时对应用环境作了许多适配.有了这两种基本的容器系列,基本上可以满足用户对IoC容器使用的大部分需求了.下面

深入理解Java的Spring框架中的IOC容器_java

Spring IOC的原型spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术,成功完成了依赖的反转:从主类的对依赖的主动管理反转为了spring容器对依赖的全局控制. 这样做的好处是什么呢? 当然就是所谓的"解耦"了,可以使得程序的各模块之间的关系更为独立,只需要spring控制这些模块之间的依赖关系并在容器启动和初始化的过程中将依据这些依赖关系创建.管理和维护这些模块就好,如果需要改变模块间的依赖关系的话,甚至都不需要改变程序代码,只需要将更

重新学习之spring第一个程序,配置IOC容器

第一步:导入相关jar包(此范例导入的是spring3.2.4版本,spring2.5版本只需要导入spring核心包即可)     第二步:在项目的src下配置applicationContext.xml的配置文件 applicationContext.xml文件   1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.o