源码学习之Spring IOC容器体系

SpringIOC介绍

           IOC,也就是我们所说控制反转,在spring中,它通过ioc容器来管理对象,包括对象的生命周期和与其他对象的关系,实现控制反转,将对象-对象 这样的关系转为 对象-容器-对象,它在程序运行时通过反射动态的提供对象来实现依赖注入(DI)。

SpringIOC容器体系

           springIOC的容器体系最重要的接口有BeanFactroy和ApplicationContext,我们将容器类型也分为BanFactory和ApplicationContext两类,其中BeanFactory代表容器的基本实现,只有容器的基础功能,ApplicationContext则被认为是容器的高级实现,在基础功能上附加了很多额外的功能以供使用。

           根据这个思路,我们来学习spring中的容器体系,按照基础实现和高级实现两条线来分析:

第一条线,容器的基本实现:BeanFactory

BeanFactory==》HierarchicalBeanFactory==》ConfigurableBeanFactory ==》…==》DefaultListableBeanFactory

 

我将UML图附上:

绿色部分是ioc容器的基本功能实现路线,

红色部分是继承了顶级接口BeanFactory的三个二级几口

扫描二维码关注公众号,回复: 5917719 查看本文章

简单介绍下这些:

BeanFactory:顶级接口,定义了容器的基本规范:getBean() etc.

HierarchicalBeanFactory(二级接口):双亲Ioc容器的概念,还记得上一篇解析CntextLoaderListener中我们提到过:CntextLoaderListener和DispatcherServlet共同建立springMVC中的ioc容器体系,其中CntextLoaderListener创建的是Root WebApplicationContext,是作为DispatcherServlet创建的springMVC WebApplication的双亲容器存在的,这个双亲的概念就是从HierarchicalBeanFactory开始的。

ListableBeanFactory(二级接口)引入beanDefinition的概念,将容器中的bean对象以集合

形式获取,不需要通过名称一个个来获取,将容器需要实现类似预加载所有beanDefinition的功能时可以通过该接口实现。

AutowireCapableBeanFactory(二级接口)通过源码上的注释我们可以了解到这个接口的作用是让那些非spring管理的对象也能拥有spring自动注入的特性。同时spring中常问到的spring中的装配方式也是在这边提到的:

/**
 * Constant that indicates no externally defined autowiring. Note that
 * BeanFactoryAware etc and annotation-driven injection will still be applied.
 * @see #createBean
 * @see #autowire
 * @see #autowireBeanProperties
 */
int AUTOWIRE_NO = 0;

/**
 * Constant that indicates autowiring bean properties by name
 * (applying to all bean property setters).
 * @see #createBean
 * @see #autowire
 * @see #autowireBeanProperties
 */
int AUTOWIRE_BY_NAME = 1;

/**
 * Constant that indicates autowiring bean properties by type
 * (applying to all bean property setters).
 * @see #createBean
 * @see #autowire
 * @see #autowireBeanProperties
 */
int AUTOWIRE_BY_TYPE = 2;

/**
 * Constant that indicates autowiring the greediest constructor that
 * can be satisfied (involves resolving the appropriate constructor).
 * @see #createBean
 * @see #autowire
 */
int AUTOWIRE_CONSTRUCTOR = 3;

/**
 * Constant that indicates determining an appropriate autowire strategy
 * through introspection of the bean class.
 * @see #createBean
 * @see #autowire
 * @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
 * prefer annotation-based autowiring for clearer demarcation of autowiring needs.
 */
@Deprecated
int AUTOWIRE_AUTODETECT = 4;

 

ConfigurableBeanFactory:提供一系列可插拔的配置项,填充BeanFactory的功能。

DeFaultLsitableBeanFactory:这个类是这条设计线的第一个具体实现类,它实现了ioc容器的所有基本功能。

 

第二条线,容器的高级实现:ApplicationContext

BeanFactory==》ListableBeanFactory==》Application==》WebApplication

我将UML图附上:

绿色部分是ioc容器的高级功能的实现路线

红色部分是最终的几个具体实现类:

ApplicationContext:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
      MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
之所以说ApplicationContext是ioc容器的高级实现,是因为他在beanFactory的基础功能上附加了很多其他功能来对应用实现支持,这部分附加的内容主要就是通过继承的这些类实现:
 * Central interface to provide configuration for an application.
 * This is read-only while the application is running, but may be
 * reloaded if the implementation supports this.
 *
 * <p>An ApplicationContext provides:
 * <ul>
 * <li>Bean factory methods for accessing application components.
 * Inherited from {@link org.springframework.beans.factory.ListableBeanFactory}.
 * <li>The ability to load file resources in a generic fashion.
 * Inherited from the {@link org.springframework.core.io.ResourceLoader} interface.
 * <li>The ability to publish events to registered listeners.
 * Inherited from the {@link ApplicationEventPublisher} interface.
 * <li>The ability to resolve messages, supporting internationalization.
 * Inherited from the {@link MessageSource} interface.
 * <li>Inheritance from a parent context. Definitions in a descendant context
 * will always take priority. This means, for example, that a single parent
 * context can be used by an entire web application, while each servlet has
 * its own child context that is independent of that of any other servlet.
 * </ul>
ApplicationContext为应用提供配置,通过:
ListableBeanFactory可以访问应用中的组件;
ResourceLoader可以加载资源;
ApplicationEventPublisher可以注册监听器分发事件;
MessageSource可以支持国际化;

WeblicationContext:

public interface WebApplicationContext extends ApplicationContext {

   /**
    * Context attribute to bind root WebApplicationContext to on successful startup.
    * <p>Note: If the startup of the root context fails, this attribute can contain
    * an exception or error as value. Use WebApplicationContextUtils for convenient
    * lookup of the root WebApplicationContext.
    * @see org.springframework.web.context.support.WebApplicationContextUtils#getWebApplicationContext
    * @see org.springframework.web.context.support.WebApplicationContextUtils#getRequiredWebApplicationContext
    */
   String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

   /**
    * Scope identifier for request scope: "request".
    * Supported in addition to the standard scopes "singleton" and "prototype".
    */
   String SCOPE_REQUEST = "request";

   /**
    * Scope identifier for session scope: "session".
    * Supported in addition to the standard scopes "singleton" and "prototype".
    */
   String SCOPE_SESSION = "session";

   /**
    * Scope identifier for global session scope: "globalSession".
    * Supported in addition to the standard scopes "singleton" and "prototype".
    */
   String SCOPE_GLOBAL_SESSION = "globalSession";

   /**
    * Scope identifier for the global web application scope: "application".
    * Supported in addition to the standard scopes "singleton" and "prototype".
    */
   String SCOPE_APPLICATION = "application";

   /**
    * Name of the ServletContext environment bean in the factory.
    * @see javax.servlet.ServletContext
    */
   String SERVLET_CONTEXT_BEAN_NAME = "servletContext";

   /**
    * Name of the ServletContext/PortletContext init-params environment bean in the factory.
    * <p>Note: Possibly merged with ServletConfig/PortletConfig parameters.
    * ServletConfig parameters override ServletContext parameters of the same name.
    * @see javax.servlet.ServletContext#getInitParameterNames()
    * @see javax.servlet.ServletContext#getInitParameter(String)
    * @see javax.servlet.ServletConfig#getInitParameterNames()
    * @see javax.servlet.ServletConfig#getInitParameter(String)
    */
   String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";

   /**
    * Name of the ServletContext/PortletContext attributes environment bean in the factory.
    * @see javax.servlet.ServletContext#getAttributeNames()
    * @see javax.servlet.ServletContext#getAttribute(String)
    */
   String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";


   /**
    * Return the standard Servlet API ServletContext for this application.
    * <p>Also available for a Portlet application, in addition to the PortletContext.
    */
   ServletContext getServletContext();

}
 

重点是最后一个方法:

/**
 * Return the standard Servlet API ServletContext for this application.
 * <p>Also available for a Portlet application, in addition to the PortletContext.
 */
ServletContext getServletContext();
通过这个方法将spring中的ioc容器与web应用中的ServletContext联系起来。

 

总结

           从UML图可以看到,整个ioc体系是非常复杂的,在面向接口+单一职责的设计下,一个庞大的接口体系成型,这样设计的好处是显而易见的,我们可以非常方便的设计出符合自己需求的容器,打造自定义的容器以供使用。

           这里只是简单介绍了springIOC容器,后面会更加深入的进行解析,同时会通过阅读源码穿插设计模式的内容。

猜你喜欢

转载自blog.csdn.net/qq_23585245/article/details/89341546