• 最后的记忆——Spring ApplicationContext


    本文尝试分析一下Spring 的 ApplicationContext体系的 接口设计,尝试理解为什么这么做,为什么接口这么设计、为什么这么去实现,为什么需要有这个方法,为什么 这样命名?接口、类、方法的 大致用途是什么? 是否是最合理的?是否有完善的空间? 是否 让一个 同样顶级人才来设计,是否会得到一样的 设计和实现?

     简称:

    BeanFactory 简称bf

    ApplicationContext 简称ac

    ServletContext 简称sc

    BeanDefinition 简称bd

     

    接口/类图 

    ac的 uml 接口/类图 如下:

    以AnnotationConfigServletWebServerApplicationContext 的视角来看(ctrl+shift+alt+U)

     可以看到 ac 继承了很多的bf  接口,另外,关键的还有 ResourceLoader 接口, 这里的 Resource 我认为主要就是 bd, properties文件呢? 应该是另外的话题 。

    abstract ac 的下级子类 :

    DefaultResourceLoader (org.springframework.core.io)
        AbstractApplicationContext (org.springframework.context.support)
            AbstractRefreshableApplicationContext (org.springframework.context.support)
                AbstractRefreshableConfigApplicationContext (org.springframework.context.support)
                    AnnotationConfigReactiveWebApplicationContext (org.springframework.boot.web.reactive.context)
                    AbstractXmlApplicationContext (org.springframework.context.support)
                        FileSystemXmlApplicationContext (org.springframework.context.support)
                        ClassPathXmlApplicationContext (org.springframework.context.support)
                    AbstractRefreshableWebApplicationContext (org.springframework.web.context.support)
                        XmlWebApplicationContext (org.springframework.web.context.support)
                        GroovyWebApplicationContext (org.springframework.web.context.support)
                        AnnotationConfigWebApplicationContext (org.springframework.web.context.support)
            GenericApplicationContext (org.springframework.context.support)
                GenericXmlApplicationContext (org.springframework.context.support)
                StaticApplicationContext (org.springframework.context.support)
                    StaticWebApplicationContext (org.springframework.web.context.support)
                GenericWebApplicationContext (org.springframework.web.context.support)
                    ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
                        AnnotationConfigServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
                        XmlServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
                ResourceAdapterApplicationContext (org.springframework.jca.context)
                GenericGroovyApplicationContext (org.springframework.context.support)
                AnnotationConfigApplicationContext (org.springframework.context.annotation)
                GenericReactiveWebApplicationContext (org.springframework.boot.web.reactive.context)
                    ReactiveWebServerApplicationContext (org.springframework.boot.web.reactive.context)
                        AnnotationConfigReactiveWebServerApplicationContext (org.springframework.boot.web.reactive.context)

    接口描述

    ================================== ApplicationContext ==================================


    ac 定义如下:
    public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

    String getId();

    String getApplicationName();// ApplicationName 和 id 什么区别?

    String getDisplayName();

    long getStartupDate();

    @Nullable
    ApplicationContext getParent(); // Nullable表示 可能没有 父

    AutowireCapableBeanFactory getAutowireCapableBeanFactory()
    }


    非常简单,似乎并没有什么实用的 功能特性..

    ApplicationContext 全是 get(获取)属性:id、applicationName、displayName、startupDate、parent、autowireCapableBeanFactory
    注意这里的parent 是ApplicationContext,而 HierarchicalBeanFactory 的 parentBeanFactory 是BeanFactory 类型

    ================================== 插播 ==================================

    public interface Lifecycle {
    void start();

    void stop();

    boolean isRunning();
    }

    AliasRegistry: 对alias 的增删改查

    public interface AliasRegistry {
    void registerAlias(String var1, String var2);

    void removeAlias(String var1);

    boolean isAlias(String var1);

    String[] getAliases(String var1);
    }

    BeanDefinitionRegistry 对bd 的增删改查
    —— XxxRegistry 命名格式的类 有什么特殊?
    —— 注意 一个name只对应一个bd,正如一个name对应一个bean; 一一对应关系!
    public interface BeanDefinitionRegistry extends AliasRegistry {
    void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;

    void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    boolean containsBeanDefinition(String var1);

    String[] getBeanDefinitionNames();

    int getBeanDefinitionCount();

    boolean isBeanNameInUse(String var1);
    }


    ================================== WebApplicationContext ==================================
    WebApplicationContext
    关键是可以获取Servlet上下文 ServletContext

    public interface WebApplicationContext extends ApplicationContext {
    String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
    String SCOPE_REQUEST = "request";
    String SCOPE_SESSION = "session";
    String SCOPE_APPLICATION = "application";
    String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
    String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
    String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";

    @Nullable
    ServletContext getServletContext(); // 关键方法!!!
    }


    ================================== WebServerApplicationContext ==================================

    WebServerApplicationContext 可以获取属性:webServer、serverNamespace, 分别是什么作用??
    webServer是对 Tomcat、jetty 的抽象,代表可以运行的web 服务器程序
    serverNamespace 是

    public interface WebServerApplicationContext extends ApplicationContext {
    WebServer getWebServer();
    String getServerNamespace();
    }

    ++++++++++++++++++++++++++++++++++ ConfigurableApplicationContext ++++++++++++++++++++++++++++++++++
    ConfigurableApplicationContext

    Configurable 可配置,可配置什么?id、parent、env、添加BeanFactoryPostProcessor、添加ApplicationListener、添加ProtocolResolver
    这里的配置 是设置的 意思! 作为一个接口,它可以设置x属性意味着什么,意味着它必然可以获取那个x!
    BeanFactoryPostProcessor 是一个非常强大的东西,可以添加BeanFactoryPostProcessor,意味着可以对bf很多扩展,可以玩出花来!
    ApplicationListener 是做监听等作用。
    ProtocolResolver是..

    注意 这个类涉及比较多的Environment操作, 既可以set也可以get,全能Environment 选手。
    而且这里的Environment 又是Configurable的

    定义如下:
    public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
    String CONFIG_LOCATION_DELIMITERS = ",; ";
    String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
    String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
    String ENVIRONMENT_BEAN_NAME = "environment";
    String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
    String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";

    void setId(String var1);

    void setParent(@Nullable ApplicationContext var1);

    void setEnvironment(ConfigurableEnvironment var1);

    ConfigurableEnvironment getEnvironment();

    void addBeanFactoryPostProcessor(BeanFactoryPostProcessor var1);

    void addApplicationListener(ApplicationListener<?> var1);

    void addProtocolResolver(ProtocolResolver var1);

    void refresh() throws BeansException, IllegalStateException; // 重要方法,首次定义!

    void registerShutdownHook();

    void close();

    boolean isActive();

    ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
    }

    ================================== ConfigurableWebServerApplicationContext ==================================

    ConfigurableWebServerApplicationContext 额外继承了 WebServerApplicationContext, 主要有set serverNamespace 方法

    ———— 为什么要分这么细? 这里的set ServerNamespace 不能合并到 WebServerApplicationContext?分这么细? ———— 主要是 体现一个 Configurable!!~
    ———— Configurable类,一定有 set方法 ?好像是这样

    public interface ConfigurableWebServerApplicationContext extends ConfigurableApplicationContext, WebServerApplicationContext {
    void setServerNamespace(String serverNamespace);
    }


    ================================== ConfigurableWebApplicationContext ==================================

    它跟 ConfigurableWebServerApplicationContext 非常类似, 容易混淆。 区分一下:
    Configurable Web ac extends ConfigurableApplicationContext, Web ac
    Configurable Web Server ac extends ConfigurableApplicationContext, Web Server ac
    接口 名字差别仅仅是 一个单词 Server, 继承的父 接口也是 差别同一个单词


    ConfigurableWebApplicationContext
    Configurable 可配置,可配置什么? 设置sc、Namespace、ServletConfig、ConfigLocation,并可以获取Namespace、ServletConfig、 ConfigLocation (基本上就是同时getter、setter)—— 这些都是webapp 必须的东西!
    sc的getter呢? WebApplicationContext 定义的!
    可以看到,虽然是少了个单词Server,但是它的 方法比 Configurable Web Server ac 多一些。它才是 主接口!

    定义如下:
    public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {
    String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":";
    String SERVLET_CONFIG_BEAN_NAME = "servletConfig";

    void setServletContext(@Nullable ServletContext var1);

    void setServletConfig(@Nullable ServletConfig var1);

    @Nullable
    ServletConfig getServletConfig();

    void setNamespace(@Nullable String var1);

    @Nullable
    String getNamespace();

    void setConfigLocation(String var1);

    void setConfigLocations(String... var1);

    @Nullable
    String[] getConfigLocations();
    }

    接口实现说明


    ++++++++++++++++++++++++++++++++++ AbstractApplicationContext ++++++++++++++++++++++++++++++++++

    AbstractApplicationContext 是一个重量级的 类: 很重,他的主要内容 就是 实现了哪些个接口,最重要的方法是 refresh, 其他的方法几乎都是为了而存在的。其他的私有方法更加如此。几乎可以忽略。 简单来说,它 bf,Configurable,Listable,具有ac特性,Hierarchical, 国际化特性, lifecycle特性
    public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
    ...
    }

    它继承了ConfigurableApplicationContext,但是呢,似乎没有任何 web 的功能!!!!


    方法
    AbstractApplicationContext()
    AbstractApplicationContext(context.ApplicationContext)
    setDisplayName
    createEnvironment
    publishEvent(java.lang.Object, core.ResolvableType)
    getApplicationEventMulticaster
    getLifecycleProcessor
    getResourcePatternResolver
    getBeanFactoryPostProcessors
    getApplicationListeners
    prepareRefresh
    initPropertySources
    obtainFreshBeanFactory
    prepareBeanFactory
    postProcessBeanFactory
    invokeBeanFactoryPostProcessors
    registerBeanPostProcessors
    initMessageSource
    initApplicationEventMulticaster
    initLifecycleProcessor
    onRefresh
    registerListeners
    finishBeanFactoryInitialization
    finishRefresh
    cancelRefresh
    resetCommonCaches
    destroy
    doClose
    destroyBeans
    onClose
    assertBeanFactoryActive
    getInternalParentBeanFactory //
    getMessageSource
    getInternalParentMessageSource
    refreshBeanFactory
    closeBeanFactory


    MESSAGE_SOURCE_BEAN_NAME
    LIFECYCLE_PROCESSOR_BEAN_NAME
    APPLICATION_EVENT_MULTICASTER_BEAN_NAME

    属性, 同时有getter、setter
    logger
    id
    displayName
    parent ApplicationContext
    environment ConfigurableEnvironment
    beanFactoryPostProcessors List<BeanFactoryPostProcessor>
    startupDate
    active
    closed
    startupShutdownMonitor Object
    shutdownHook Thread
    resourcePatternResolver ResourcePatternResolver
    lifecycleProcessor LifecycleProcessor
    messageSource MessageSource
    applicationEventMulticaster
    applicationListeners Set<ApplicationListener<?>>
    earlyApplicationEvents Set<ApplicationEvent>

    对 其他
    ConfigurableApplicationContext:
    setId
    setEnvironment
    getEnvironment
    setParent
    addBeanFactoryPostProcessor
    addApplicationListener
    refresh // !!!!!!!! 最最重要的 实现方法 在此, 是核心, 是关键。 其他大部分方法因她存在 !!!!!!!!
    registerShutdownHook
    close
    isActive

    ConfigurableApplicationContext:
    getBeanFactory

    ApplicationContext:
    getId
    getApplicationName
    getDisplayName
    getParent
    getAutowireCapableBeanFactory
    getStartupDate

    ApplicationEventPublisher:
    publishEvent(context.ApplicationEvent)
    publishEvent(java.lang.Object)


    bf:
    getBean(java.lang.String) // 这里的 很多方法, 其实是代理方法,具体的工作实际上是内部的 BeanFactory 代理完成的 !
    getBean(java.lang.String, java.lang.Class<T>)
    getBean(java.lang.String, java.lang.Object...)
    getBean(java.lang.Class<T>)
    getBean(java.lang.Class<T>, java.lang.Object...)
    containsBean
    isSingleton
    isPrototype
    isTypeMatch(java.lang.String, core.ResolvableType)
    isTypeMatch(java.lang.String, java.lang.Class<?>)
    getType
    getAliases

    ListableBeanFactory: // 这里的 很多方法, 其实是代理方法,具体的工作实际上是内部的 BeanFactory 代理完成的 !
    containsBeanDefinition
    getBeanDefinitionCount
    getBeanDefinitionNames
    getBeanNamesForType(core.ResolvableType)
    getBeanNamesForType(java.lang.Class<?>)
    getBeanNamesForType(java.lang.Class<?>, boolean, boolean)
    getBeansOfType(java.lang.Class<T>)
    getBeansOfType(java.lang.Class<T>, boolean, boolean)
    getBeanNamesForAnnotation
    getBeansWithAnnotation
    findAnnotationOnBean

    HierarchicalBeanFactory: // 这里的 很多方法, 其实是代理方法,具体的工作实际上是内部的 BeanFactory 代理完成的 !
    getParentBeanFactory
    containsLocalBean

    MessageSource: // 这里的 方法, 也是代理方法 this.getMessageSource().xx
    getMessage(java.lang.String, java.lang.Object[], java.lang.String, java.util.Locale)
    getMessage(java.lang.String, java.lang.Object[], java.util.Locale)
    getMessage(context.MessageSourceResolvable, java.util.Locale)
    getResources

    Lifecycle:
    start
    stop
    isRunning

    toString
    AbstractApplicationContext()


    ++++++++++++++++++++++++++++++++++ GenericApplicationContext ++++++++++++++++++++++++++++++++++

    GenericApplicationContext 在上面的 abstract ac 上增加了 bd registry 的功能,同时覆盖或 实现了某些aac 的方法:
    是一个基础的、通用的 ac
    主要的实现逻辑是: 实例化一个 DefaultListableBeanFactory,ResourceLoader 可以配置化,

    新增的 重要方法 : registerBean, 可以直接注册bd对应的类型,而不用设置name,name则通过BeanDefinitionCustomizer设置。

    public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

    setParent
    getResources
    cancelRefresh
    getAutowireCapableBeanFactory

    getResource
    setClassLoader
    getClassLoader

    refreshBeanFactory
    closeBeanFactory
    getBeanFactory

    registerBeanDefinition
    removeBeanDefinition
    getBeanDefinition
    isBeanNameInUse

    registerAlias
    removeAlias
    isAlias

    GenericApplicationContext()
    GenericApplicationContext(beans.factory.support.DefaultListableBeanFactory)
    GenericApplicationContext(context.ApplicationContext)
    GenericApplicationContext(beans.factory.support.DefaultListableBeanFactory, context.ApplicationContext)
    setAllowBeanDefinitionOverriding
    setAllowCircularReferences
    setResourceLoader
    getDefaultListableBeanFactory

    ///////// 新增的 重要方法 !
    registerBean(java.lang.Class<T>, beans.factory.config.BeanDefinitionCustomizer...)
    registerBean(java.lang.String, java.lang.Class<T>, beans.factory.config.BeanDefinitionCustomizer...)
    registerBean(java.lang.Class<T>, java.util.function.Supplier<T>, beans.factory.config.BeanDefinitionCustomizer...)
    registerBean(java.lang.String, java.lang.Class<T>, java.util.function.Supplier<T>, beans.factory.config.BeanDefinitionCustomizer...)

    beanFactory DefaultListableBeanFactory
    resourceLoader ResourceLoader
    customClassLoader boolean
    refreshed AtomicBoolean

    resourceLoader: ResourceLoader
    allowBeanDefinitionOverriding: boolean
    allowCircularReferences: boolean
    defaultListableBeanFactory: DefaultListableBeanFactory


    public void setParent(@Nullable ApplicationContext parent) {
    super.setParent(parent);
    this.beanFactory.setParentBeanFactory(this.getInternalParentBeanFactory());
    }

    public interface BeanDefinitionCustomizer {
    void customize(BeanDefinition var1);
    }


    ++++++++++++++++++++++++++++++++++ GenericWebApplicationContext ++++++++++++++++++++++++++++++++++

    主要是实现了 postProcessBeanFactory 方法,另外很多的方法是 UnsupportedOperationException,需要子类实现。

    public class GenericWebApplicationContext extends GenericApplicationContext implements ConfigurableWebApplicationContext, ThemeSource {

    GenericWebApplicationContext
    setServletContext
    setServletConfig
    getServletConfig UnsupportedOperationException
    setNamespace
    getNamespace UnsupportedOperationException
    setConfigLocation UnsupportedOperationException
    setConfigLocations UnsupportedOperationException
    getConfigLocations UnsupportedOperationException

    getServletContext

    getApplicationName

    createEnvironment
    postProcessBeanFactory
    onRefresh
    initPropertySources
    getResourcePatternResolver

    getResourceByPath

    getTheme

    GenericWebApplicationContext()
    GenericWebApplicationContext(javax.servlet.ServletContext)
    GenericWebApplicationContext(support.DefaultListableBeanFactory)
    GenericWebApplicationContext(support.DefaultListableBeanFactory, javax.servlet.ServletContext)


    主要属性:
    servletContext
    themeSource


    @Nullable
    private ServletContext servletContext;
    @Nullable
    private ThemeSource themeSource;

    可见, 它几乎仅仅是提供了 servletContext themeSource 的属性配置功能。

    另外,postProcessBeanFactory 比较重要:
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    if (this.servletContext != null) {
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    }

    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
    }

    ++++++++++++++++++++++++++++++++++ ServletWebServerApplicationContext ++++++++++++++++++++++++++++++++++

    ServletWebServerApplicationContext 是 Spring boot 的内容。

    主要实现了 ConfigurableWebServerApplicationContext, GenericWebApplicationContext
    通过实现 Servlet,实现了 WebServer 的大部分逻辑,实现了很多的 ConfigurableWebServerApplicationContext 的空方法
    主要方法是 createWebServer startWebServer stopAndReleaseWebServer ... 另外 selfInitialize 也做了一些事情

    然后是 prepareWebApplicationContext(ServletContext servletContext) ,
    Object rootContext = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); // this
    this.setServletContext(servletContext);

    WebApplicationContextUtils registerWebApplicationScopes

    WebApplicationContextUtils registerEnvironmentBeans

    补充:
    ServletContextInitializer
    public interface ServletContextInitializer {
    void onStartup(ServletContext servletContext) throws ServletException;
    }

    ExistingWebApplicationScopes
    restore


    定义如下:
    public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext {

    }

    ServletWebServerApplicationContext
    ExistingWebApplicationScopes
    ExistingWebApplicationScopes#null
    ExistingWebApplicationScopes#ExistingWebApplicationScopes
    ExistingWebApplicationScopes#restore
    ExistingWebApplicationScopes#SCOPES
    ExistingWebApplicationScopes#beanFactory
    ExistingWebApplicationScopes#scopes
    postProcessBeanFactory
    onRefresh
    getResourceByPath
    setServletConfig
    getServletConfig
    refresh // 这里的 refresh 是主要是异常处理,具体工作是 super.refresh();
    finishRefresh
    onClose
    getServerNamespace
    getWebServer
    setServerNamespace
    ServletWebServerApplicationContext()
    ServletWebServerApplicationContext(support.DefaultListableBeanFactory)
    createWebServer
    selfInitialize
    prepareWebApplicationContext
    startWebServer
    stopAndReleaseWebServer
    getWebServerFactory
    getSelfInitializer
    getServletContextInitializerBeans

    logger
    DISPATCHER_SERVLET_NAME

    主要属性:
    webServer
    servletConfig
    serverNamespace


    ++++++++++++++++++++++++++++++++++ TomcatWebServer ++++++++++++++++++++++++++++++++++

    public interface WebServer {
    void start() throws WebServerException;

    void stop() throws WebServerException;

    int getPort();
    }

    public class TomcatWebServer implements WebServer {..


    TomcatWebServer
    start
    stop
    TomcatWebServer
    TomcatWebServer
    initialize
    findContext
    addInstanceIdToEngineName
    removeServiceConnectors
    rethrowDeferredStartupExceptions
    startDaemonAwaitThread
    checkThatConnectorsHaveStarted
    stopSilently
    stopTomcat
    addPreviouslyRemovedConnectors
    stopProtocolHandler
    performDeferredLoadOnStartup
    getPortsDescription
    logger
    containerCounter
    monitor
    autoStart
    started

    ++++++++++++++++++++++++++++++++++ 补充 ++++++++++++++++++++++++++++++++++

    AnnotationConfigRegistry 是一个简单的类, 通过class 注册 ,通过 scan扫描 package name 解析 annotation 注解,然后再调用第一个方法去 register 扫描到的class 实例
    public interface AnnotationConfigRegistry {
    void register(Class<?>... var1);
    void scan(String... var1);
    }

    public interface BeanNameGenerator {
    String generateBeanName(BeanDefinition var1, BeanDefinitionRegistry var2);
    }

    ScopeMetadataResolver 有些难理解。。
    public interface ScopeMetadataResolver {
    ScopeMetadata resolveScopeMetadata(BeanDefinition var1);
    }


    ++++++++++++++++++++++++++++++++++ AnnotationConfigServletWebServerApplicationContext ++++++++++++++++++++++++++++++++++

    AnnotationConfigServletWebServer ac 是集大成者, 通过一系列的集成, 它已经非常的丰满。它大部分是一些set/get,主要方法是 postProcessBeanFactory

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    super.postProcessBeanFactory(beanFactory);
    if (this.basePackages != null && this.basePackages.length > 0) {
    this.scanner.scan(this.basePackages);
    }

    if (!this.annotatedClasses.isEmpty()) {
    this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
    }
    }

    可以看到, 它主要是 先通过scanner.scan 去扫描 获取bd,放置到 registry(也就是自身, registry 也是bf,因为bf 继承了registry), 然后调用 reader.register,(reader 也是bf,因为bf),scanner、reader 都拥有 自身的引用,他们相互引用。。。 这样完后,AnnotationConfigServletWebServer ac 它自己就可以获取所有的bd,也有拥有了所有的 bd!

    实际上scanner.scan、reader.register 是很耗时的, 里面的处理逻辑非常的复杂,特别是涉及到 ConfigurationClass 这一块。 因为它的 功能实在太强大。(后续展开)


    签名:
    public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {

    }


    AnnotationConfigServletWebServerApplicationContext
    prepareRefresh
    setEnvironment
    register
    scan
    postProcessBeanFactory
    AnnotationConfigServletWebServerApplicationContext()
    AnnotationConfigServletWebServerApplicationContext(support.DefaultListableBeanFactory)
    AnnotationConfigServletWebServerApplicationContext(java.lang.Class<?>...)
    AnnotationConfigServletWebServerApplicationContext(java.lang.String...)

    setBeanNameGenerator
    setScopeMetadataResolver

    主要属性:
    reader AnnotatedBeanDefinitionReader
    scanner ClassPathBeanDefinitionScanner
    annotatedClasses Set<Class<?>>
    basePackages String[]


    private final AnnotatedBeanDefinitionReader reader;
    private final ClassPathBeanDefinitionScanner scanner;
    private final Set<Class<?>> annotatedClasses;
    private String[] basePackages;


    ++++++++++++++++++++++++++++++++++ AbstractRefreshableApplicationContext ++++++++++++++++++++++++++++++++++

    签名:
    public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext implements ConfigurableWebApplicationContext, ThemeSource {

    }

    refreshBeanFactory
    closeBeanFactory
    getBeanFactory
    cancelRefresh
    assertBeanFactoryActive
    AbstractRefreshableApplicationContext()
    AbstractRefreshableApplicationContext(org.springframework.context.ApplicationContext)
    hasBeanFactory
    createBeanFactory
    customizeBeanFactory
    loadBeanDefinitions
    setAllowBeanDefinitionOverriding
    setAllowCircularReferences
    allowBeanDefinitionOverriding
    allowCircularReferences
    beanFactory
    beanFactoryMonitor


    主要属性是:
    @Nullable
    private Boolean allowBeanDefinitionOverriding;
    @Nullable
    private Boolean allowCircularReferences;
    @Nullable
    private DefaultListableBeanFactory beanFactory;
    private final Object beanFactoryMonitor = new Object();

    主要方法是
    protected final void refreshBeanFactory() throws BeansException {
    if (this.hasBeanFactory()) {
    this.destroyBeans();
    this.closeBeanFactory();
    }

    try {
    DefaultListableBeanFactory beanFactory = this.createBeanFactory();
    beanFactory.setSerializationId(this.getId());
    this.customizeBeanFactory(beanFactory);
    this.loadBeanDefinitions(beanFactory);
    synchronized(this.beanFactoryMonitor) {
    this.beanFactory = beanFactory;
    }
    } catch (IOException var5) {
    throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
    }
    }

    实现了 客制化! 让 allowCircularReferences allowBeanDefinitionOverriding 属性 可配置!


    ++++++++++++++++++++++++++++++++++ AbstractRefreshableConfigApplicationContext ++++++++++++++++++++++++++++++++++

    签名:
    public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext implements BeanNameAware, InitializingBean {
    }

    setId
    setBeanName
    afterPropertiesSet
    AbstractRefreshableConfigApplicationContext()
    AbstractRefreshableConfigApplicationContext(org.springframework.context.ApplicationContext)
    resolvePath
    getConfigLocations
    configLocations
    setConfigLocation
    setConfigLocations
    getDefaultConfigLocations
    setIdCalled


    主要属性是:
    private String[] configLocations;
    private boolean setIdCalled = false;
    可见, 主要是提供了 config文件的位置的 配置化!


    ++++++++++++++++++++++++++++++++++ AbstractRefreshableWebApplicationContext ++++++++++++++++++++++++++++++++++

    AbstractRefreshableWebApplicationContext

    签名:
    public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext implements ConfigurableWebApplicationContext, ThemeSource {
    }

    @Nullable
    private ServletContext servletContext;
    @Nullable
    private ServletConfig servletConfig;
    @Nullable
    private String namespace;
    @Nullable
    private ThemeSource themeSource;

    AbstractRefreshableWebApplicationContext
    setServletContext
    setServletConfig
    getServletConfig
    setNamespace
    getNamespace
    getConfigLocations
    getServletContext
    getApplicationName
    createEnvironment
    postProcessBeanFactory
    onRefresh
    initPropertySources
    getResourcePatternResolver
    getResourceByPath
    getTheme
    AbstractRefreshableWebApplicationContext

    主要属性:
    servletContext
    servletConfig
    namespace
    themeSource

    其实主要就是提供了 servletContext servletConfig namespace 的getter、setter 然后在 postProcessBeanFactory 进行各种 后处理:

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
    }


    ++++++++++++++++++++++++++++++++++ AbstractXmlApplicationContext ++++++++++++++++++++++++++++++++++

    public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
    }

    AbstractXmlApplicationContext
    AbstractXmlApplicationContext
    initBeanDefinitionReader
    loadBeanDefinitions
    setValidating

    validating //重要属性


    ++++++++++++++++++++++++++++++++++ FileSystemXmlApplicationContext ++++++++++++++++++++++++++++++++++

    主要是提供了 多个构造函数, 可以通过指定 xml文件的 FileSystem 位置来 配置 ac
    public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {
    }


    ++++++++++++++++++++++++++++++++++ ClassPathXmlApplicationContext ++++++++++++++++++++++++++++++++++

    主要是提供了 多个构造函数, 可以通过指定 xml文件的 ClassPath 位置来 配置 ac
    public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
    }

    主要属性是:
    private Resource[] configResources;

    ClassPath 和 FileSystem 有什么区别? 有细微的。。

    ++++++++++++++++++++++++++++++++++ XmlWebApplicationContext ++++++++++++++++++++++++++++++++++


    签名:
    public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {

    }

    XmlWebApplicationContext

    主要方法是
    getDefaultConfigLocations
    initBeanDefinitionReader
    loadBeanDefinitions(support.DefaultListableBeanFactory)
    loadBeanDefinitions(xml.XmlBeanDefinitionReader) // 重要方法: 通过XmlBeanDefinitionReader,读取xml,解析为 bd

    public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
    public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
    public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";


    namespace 的作用? 如何配置?
    protected String[] getDefaultConfigLocations() {
    return this.getNamespace() != null ? new String[]{"/WEB-INF/" + this.getNamespace() + ".xml"} : new String[]{"/WEB-INF/applicationContext.xml"};
    }

    org.xml.sax.InputSource
    InputSource()
    InputSource(java.lang.String)
    InputSource(java.io.InputStream)
    InputSource(java.io.Reader)

    ++++++++++++++++++++++++++++++++++ AnnotationConfigWebApplicationContext ++++++++++++++++++++++++++++++++++

    public class AnnotationConfigWebApplicationContext extends AbstractRefreshableWebApplicationContext implements AnnotationConfigRegistry {
    }


    register
    scan
    loadBeanDefinitions // 主要方法!!!!重量级方法, 这里调用了 scanner、reader 的方法
    AnnotationConfigWebApplicationContext
    getAnnotatedBeanDefinitionReader
    getClassPathBeanDefinitionScanner
    setBeanNameGenerator
    getBeanNameGenerator
    beanNameGenerator
    setScopeMetadataResolver
    getScopeMetadataResolver


    主要属性是:
    scopeMetadataResolver
    annotatedClasses
    basePackages


    private BeanNameGenerator beanNameGenerator;
    @Nullable
    private ScopeMetadataResolver scopeMetadataResolver;
    private final Set<Class<?>> annotatedClasses = new LinkedHashSet();
    private final Set<String> basePackages = new LinkedHashSet();

    AnnotationConfigWebApplicationContext 竟然 不继承 AnnotationConfigApplicationContext,而两者的名字 如此的 接近! 一个是AnnotationConfig ,一个是AnnotationConfigWeb, 为什么要分这么细?对比发现, AnnotationConfigWebApplicationContext 似乎要少了 几个方法...

    总结

    观察可发现,几乎 对应每一个 类型的bf, 都有一个ac,比如listable,configurable。 ac 的功能比bf 要强大不少,当然,也复杂不少。有了ac,我们的程序就可以跑起来了。 那么什么时候我们使用ac? 什么时候用bf? 我觉得一般都是直接使用ac,bf 几乎用不得,除非底层研究的时候!

    ac 意味着一个应用程序,相当于bf 屌丝,ac 其实已经是 高富帅。他提供了很多的 高级特性,可以直接作为application 可以实际应用,可生产环境部署 ,ac 的子接口  主要都是Web,这也 好理解, Spring的主要 适用领悟是 Web application

    ac 的功能特性太多,部分还有疑问,待续。

  • 相关阅读:
    python 网络客户端编程端口,模块
    Python反转
    ASP.NET的路由系统
    yield 关键字
    C# Lock关键字
    C#中as和is关键字
    13.4 上下文对象
    请求生命周期
    ASP.NET常用的指令
    ASP.NET Page 指令
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/11798423.html
Copyright © 2020-2023  润新知