从源码层面解析SpringIOC容器

Posted ymjingspace

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从源码层面解析SpringIOC容器相关的知识,希望对你有一定的参考价值。

Spring IOC容器继承关系图

 技术图片

              MessageSource支持消息国际化。ResouceLoader资源加载。BeanFactory创建Bean。ApplicationEventPublisher通知的所有与事件相匹配的监听器。

Ioc(inverse of control)

Ioc: 控制反转,简单来说就是 把创建对象实例的行为由程序交给Spring容器来完成。这样能达到松耦合的目的。Spring容器通过解析Bean的各项参数配置来回复Bean的生命周期以及Bean与Bean之间的关系。Spring容器以此来达到对Bean的管理。

Spring中常用的接口有:BeanFactory、ApplicationContext、ConfigurableApplicationContext、ConfigurableWebApplicationContext、Xml BeanFactory、FactoryBean等等

BeanFactory

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;

public abstract interface BeanFactory

{

  public static final String FACTORY_BEAN_PREFIX = "&";

  //从factory中获取给定名称的bean

  public abstract Object getBean(String paramString)

    throws BeansException;

  //从factory中获取给定名称的bean实例

  public abstract Object getBean(String paramString, Class paramClass)

    throws BeansException;

  //从factory中获取给定名称的bean实例

  public abstract Object getBean(String paramString, Object[] paramArrayOfObject)

    throws BeansException;

  //判断factory中是否有给定名称的bean实例,有则返回true.

  public abstract boolean containsBean(String paramString);

  //判断给定名称的bean实例的作用域是否是Singleton,是则返回true.

  public abstract boolean isSingleton(String paramString)

    throws NoSuchBeanDefinitionException;

  //判断给定名称的bean实例的作用域是否是Prototype,是则返回true.

  public abstract boolean isPrototype(String paramString)

    throws NoSuchBeanDefinitionException;

  //判断factory中是否有给定type和class类型的bean实例

  public abstract boolean isTypeMatch(String paramString, Class paramClass)

    throws NoSuchBeanDefinitionException;

  //从factory中获取给定type的bean实例,并装换成class类型.

  public abstract Class getType(String paramString)

    throws NoSuchBeanDefinitionException;

  //返回给定bean名称的所有别名.

  public abstract String[] getAliases(String paramString);

}

ApplicationContext

package org.springframework.context;

import org.springframework.beans.factory.HierarchicalBeanFactory;

import org.springframework.beans.factory.ListableBeanFactory;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import org.springframework.core.io.support.ResourcePatternResolver;

public abstract interface ApplicationContext

  extends ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver

{

//获取父ApplicationContext容器

  public abstract ApplicationContext getParent();

  //获取可自动装配的bean factory

  public abstract AutowireCapableBeanFactory getAutowireCapableBeanFactory()

    throws IllegalStateException;

  //获取显示名称

  public abstract String getDisplayName();

  //获取启动时间

  public abstract long getStartupDate();

}

首先,它是个BeanFactory,可以管理、装配bean,可以有父级BeanFactory实现Bean的层级管理(具体到这里来说它可以有父级的ApplicationContext,因为ApplicationContext本身就是一个BeanFactory。这在web项目中很有用,可以使每个Servlet具有其独立的context, 所有Servlet共享一个父级的context),它还是Listable的,可以枚举出所管理的bean对象。

其次,它是一个ResourceLoader,可以加载资源文件;

再次,它可以管理一些Message实现国际化等功能;

还有,它可以发布事件给注册的Listener,实现监听机制。

ApplicationContext 接口具有两个直接子接口,分别是:

org.springframework.context.ConfigurableApplicationContext

org.springframework.web.context.WebApplicationContext

 技术图片

 

分别看这两个子接口:

(1)       public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable

这是一个在ApplicationContext基础上提供配置方法的接口。ConfigurableApplicationContext 提供了如setID()、setParent()、setEnvironment()等方法,用来配置ApplicationContext。其另外还继承了两个接口:①Lifecycle:Lifecycle接口中具有start()、stop()等方法,用于对context生命周期的管理;②Closeable:Closeable是标准JDK所提供的一个接口,用于最后关闭组件释放资源等;

(2)       public interface WebApplicationContext extends ApplicationContext

该接口仅仅在原接口基础上提供了getServletContext(),用于给servlet提供上下文信息。

这两个子接口的下一级共同子接口:

(1)       public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext

这里 ConfigurableWebApplicationContext 又将上述两个接口结合起来,提供了一个可配置、可管理、可关闭的WebApplicationContext,同时该接口还增加了setServletContext(),setServletConfig()等set方法,用于装配WebApplicationContext。

 

ApplicationContext相关接口基本上总结起来就是两大接口:

org.springframework.context.ConfigurableApplicationContext

org.springframework.web.context.ConfigurableWebApplicationContext

对于普通应用,使用ConfigurableApplicationContext 接口的实现类作为bean的管理者,对于web应用,使用ConfigurableWebApplicationContext 接口的实现类作为bean的管理者。这两个接口,从结构上讲他们是继承关系,从应用上讲他们是平级关系,在不同的领域为Spring提供强大的支撑。  

 

FactoryBean

package org.springframework.beans.factory;

public abstract interface FactoryBean

{

//返回FactoryBean创建的Bean实例,如果isSingleton()返回true,则会将实例放入Spring的单例缓存池中.

  public abstract Object getObject()

    throws Exception;

  //返回FactoryBean创建的Bean类型

  public abstract Class getObjectType();

  //判断FactoryBean创建的Bean的作用域是Singleton还是Prototype

  public abstract boolean isSingleton();

}

 注意:

1.普通Bean的创建:Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean。(通常比较复杂,这时使用FactoryBean可以通过编码方式得到一个比较简单的方案)。

2. 通过FactoryBean创建Bean:用户可以通过实现该接口定制实例化Bean的逻辑。FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

3. FactoryBean使用了装饰者模式和简单工厂模式.

以上是关于从源码层面解析SpringIOC容器的主要内容,如果未能解决你的问题,请参考以下文章

spring ioc 源码解析

手写spring+springmvc+mybatis框架篇springIOC容器

springIOC源码解析之BeanDefinition的注册

spring源码分析spring ioc容器之前生今世--DefaultListableBeanFactory源码解读

Spring框架学习[IoC容器高级特性]

Sping IOC 源码剖析