GenericApplicationContext通用应用程序上下文

作用

1、继承AbstractApplicationContext,几乎可以把GenericApplicationContext等价于DefaultListableBeanFactory + 上下文刷新等其他功能

  ①该实现内部有一个 DefaultListableBeanFactory 实例,GenericApplicationContext基本就是对DefaultListableBeanFactory 做了个简易的封装,几乎所有方法都是使用了DefaultListableBeanFactory的方法去实现。

  ②可以采用混合方式处理bean的定义,而不是采用特定的bean定义方式来创建bean。

2、会暴露出底层关联的DefaultListableBeanFactory对象,ConfigurableListableBeanFactory getBeanFactory()

  ①基于底层关联的DefaultListableBeanFactory对象实现BeanDefinitionRegistry接口

 ②同时可以提供一些方法对DefaultListableBeanFactory的属性进行设置,比如setApplicationStartup、setAllowBeanDefinitionOverriding、setAllowCircularReferences等

   

3、支持设置ResourceLoader,重写了Resource getResource和Resource[] getResources,优先使用自定义的 ResourceLoader获取指定路径的资源 ;在处理Resource时,支持自定义的类加载器,如果没有自定义设置且设置了ResourceLoader,就取ResourceLoader里的

4、实现了AbstractApplicationContext类的模板方法

  ①obtainFreshBeanFactory刷新底层容器阶段的抽象方法refreshBeanFactory的实现


protected final void refreshBeanFactory() throws IllegalStateException {
   if (!this.refreshed.compareAndSet(false, true)) { throw new IllegalStateException() }
   this.beanFactory.setSerializationId(getId());
}

 ②refreshBeanFactory/cancelRefresh/closeBeanFactory方法的实现,只是简单的对beanFactory.setSerializationId得设置为null


protected final void closeBeanFactory() {
   this.beanFactory.setSerializationId(null);
}

5、提供一个新的注册bean定义的方法registerBean方法

   ①使用一个新的RootBeanDefinition子类ClassDerivedBeanDefinition(clazz)来封装bean定义,重写了其getPreferredConstructors方法,实现如下

通过反射clazz.getConstructors()返回公共public的构造器集合

   ②使用参数传递进来的BeanDefinitionCustomizer对BeanDefinition进行自定义处理

   ③ 把bean定义注册到容器中,this.beanFactory.registerBeanDefinition(beanName, beanDefinition);


    public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,
                                 @Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {

        //ClassDerivedBeanDefinition实现了getPreferredConstructors(),返回公共public的构造器集合
        ClassDerivedBeanDefinition beanDefinition = new GenericApplicationContext.ClassDerivedBeanDefinition(beanClass);
        if (supplier != null) {
            beanDefinition.setInstanceSupplier(supplier);
        }
        //使用BeanDefinitionCustomizerbeanDefinition进行处理
        for (BeanDefinitionCustomizer customizer : customizers) {
            customizer.customize(beanDefinition);
        }

        String nameToUse = (beanName != null ? beanName : beanClass.getName());

 //this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
        registerBeanDefinition(nameToUse, beanDefinition);
    }
}

源码

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

    private final DefaultListableBeanFactory beanFactory;

    @Nullable
    private ResourceLoader resourceLoader;

    private boolean customClassLoader = false;

    private final AtomicBoolean refreshed = new AtomicBoolean();


    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
    public GenericApplicationContext(DefaultListableBeanFactory beanFactory) {this.beanFactory = beanFactory; }
    public GenericApplicationContext(@Nullable ApplicationContext parent) {
        this();
        setParent(parent);
    }
    public GenericApplicationContext(DefaultListableBeanFactory beanFactory, ApplicationContext parent) {
        this(beanFactory);
        setParent(parent);
    }

    
    @Override
    public void setParent(@Nullable ApplicationContext parent) {
        super.setParent(parent);
        this.beanFactory.setParentBeanFactory(getInternalParentBeanFactory());
    }
    public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) {
        this.beanFactory.setAllowBeanDefinitionOverriding(allowBeanDefinitionOverriding);
    }
    public void setAllowCircularReferences(boolean allowCircularReferences) {
        this.beanFactory.setAllowCircularReferences(allowCircularReferences);
    }


    //---------------------------------------------------------------------
    // ResourceLoade处理
    //---------------------------------------------------------------------
    
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
    @Override
    public Resource getResource(String location) {
        if (this.resourceLoader != null) {
            return this.resourceLoader.getResource(location);
        }
        return super.getResource(location);
    }
    @Override
    public Resource[] getResources(String locationPattern) throws IOException {
        if (this.resourceLoader instanceof ResourcePatternResolver) {
            return ((ResourcePatternResolver) this.resourceLoader).getResources(locationPattern);
        }
        return super.getResources(locationPattern);
    }
    @Override
    public void setClassLoader(@Nullable ClassLoader classLoader) {
        super.setClassLoader(classLoader);
        this.customClassLoader = true;
    }
    @Override
    @Nullable
    public ClassLoader getClassLoader() {
        if (this.resourceLoader != null && !this.customClassLoader) {
            return this.resourceLoader.getClassLoader();
        }
        return super.getClassLoader();
    }


    //---------------------------------------------------------------------
    // IAbstractApplicationContext抽象方法实现
    //---------------------------------------------------------------------

    /**
     * Do nothing: We hold a single internal BeanFactory and rely on callers
     * to register beans through our public methods (or the BeanFactory's).
     * @see #registerBeanDefinition
     */
    @Override
    protected final void refreshBeanFactory() throws IllegalStateException {
        if (!this.refreshed.compareAndSet(false, true)) {
            throw new IllegalStateException();
        }
        this.beanFactory.setSerializationId(getId());
    }
    @Override
    protected void cancelRefresh(BeansException ex) {
        this.beanFactory.setSerializationId(null);
        super.cancelRefresh(ex);
    }
    @Override
    protected final void closeBeanFactory() {
        this.beanFactory.setSerializationId(null);
    }
    @Override
    public final ConfigurableListableBeanFactory getBeanFactory() {
        return this.beanFactory;
    }
    public final DefaultListableBeanFactory getDefaultListableBeanFactory() {
        return this.beanFactory;
    }
    @Override
    public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
        assertBeanFactoryActive();
        return this.beanFactory;
    }


    //---------------------------------------------------------------------
    // 基于this.beanFactory实现BeanDefinitionRegistry方法
    //---------------------------------------------------------------------

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
        this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
    }
    @Override
    public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        this.beanFactory.removeBeanDefinition(beanName);
    }
    @Override
    public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        return this.beanFactory.getBeanDefinition(beanName);
    }
    @Override
    public boolean isBeanNameInUse(String beanName) {
        return this.beanFactory.isBeanNameInUse(beanName);
    }
    @Override
    public void registerAlias(String beanName, String alias) {
        this.beanFactory.registerAlias(beanName, alias);
    }
    @Override
    public void removeAlias(String alias) {
        this.beanFactory.removeAlias(alias);
    }
    @Override
    public boolean isAlias(String beanName) {
        return this.beanFactory.isAlias(beanName);
    }


    //---------------------------------------------------------------------
    // 新的注册bean定义的方法
    //---------------------------------------------------------------------
    public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,
                                 @Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
        ClassDerivedBeanDefinition beanDefinition = new ClassDerivedBeanDefinition(beanClass);
        if (supplier != null) {
            beanDefinition.setInstanceSupplier(supplier);
        }
        for (BeanDefinitionCustomizer customizer : customizers) {
            customizer.customize(beanDefinition);
        }

        String nameToUse = (beanName != null ? beanName : beanClass.getName());
        registerBeanDefinition(nameToUse, beanDefinition);
    }
    
    @SuppressWarnings("serial")
    private static class ClassDerivedBeanDefinition extends RootBeanDefinition {

        public ClassDerivedBeanDefinition(Class<?> beanClass) {
            super(beanClass);
        }
        public ClassDerivedBeanDefinition(ClassDerivedBeanDefinition original) {
            super(original);
        }

        @Override
        @Nullable
        public Constructor<?>[] getPreferredConstructors() {
            Class<?> clazz = getBeanClass();
            Constructor<?> primaryCtor = BeanUtils.findPrimaryConstructor(clazz);
            if (primaryCtor != null) {
                return new Constructor<?>[] {primaryCtor};
            }
            Constructor<?>[] publicCtors = clazz.getConstructors();
            if (publicCtors.length > 0) {
                return publicCtors;
            }
            return null;
        }

        @Override
        public RootBeanDefinition cloneBeanDefinition() {
            return new ClassDerivedBeanDefinition(this);
        }
    }

}

AnnotationConfigApplicationContext

AnnotationConfigRegistry接口


public interface AnnotationConfigRegistry {

    //根据传入组件文件class生成beanDefinition
    void register(Class<?>... componentClasses);

    //根据传入包名扫描特定注解表示的class生成beanDefinition
    void scan(String... basePackages);

}

作用

1、实现了AnnotationConfigRegistry接口的方法

  ①基于AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner实现


public void register(Class<?>... componentClasses) {
   this.reader.register(componentClasses);
}

public void scan(String... basePackages) {
   this.scanner.scan(basePackages);
}

2、继承GenericApplicationContext,是注解配置应用上下文的通用接口,使用有两种,一种是指定java组件类(例如添加了@Component),另一种是指定扫描路径

  ①内部基于两个组件进行实现配置类的注册,会注册对应的bean定义到BeanDefinitionMap,再调用refresh进行容器的刷新

   1) AnnotatedBeanDefinitionReader reader:会注册必要的后置处理器,如解析@Configuration,@Autowrite的后置处理类:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等

      2) ClassPathBeanDefinitionScanner scanner;

②根据不同的构造方法,使用不同的处理注解配置注册方式

   例如指定配置类的时候,其构造方法(核心方法)内的处理如下

 
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   this();
   register(componentClasses);//AnnotatedBeanDefinitionReader.register方法注册配置类
   refresh();//AbstractApplicationContext.refresh刷新容器,容器会基于注册配置类进行处理
}

 
public AnnotationConfigApplicationContext() {
   this.reader = new AnnotatedBeanDefinitionReader(this); //this表示BeanDefinitionRegistry,AnnotationConfigApplicationContext基于内部容器实现此接口
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}

3、暴露一些方法对这两个组件的属性进行设置,如这种beanName生成器

   
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
   this.reader.setBeanNameGenerator(beanNameGenerator);
   this.scanner.setBeanNameGenerator(beanNameGenerator);
   getBeanFactory().registerSingleton(
         AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
}

AnnotatedBeanDefinitionReader

注册@Configuration,@Autowrite的后置处理类

* 其构造方法中AnnotationConfigUtils.registerAnnotationConfigProcessors

会注册必要的后置处理器,如解析@Configuration,@Autowrite的后置处理类:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等

解析Component类Class成BeanDefinition

* 核心方法 register(Class<?>... componentClasses):开始注册配置类流程

- 使用AnnotatedGenericBeanDefinition来封装参数中指定的配置类

- 设置好abd.setInstanceSupplier(supplier)和abd.setScope(基于@Scope获取,包括scopeName、scopedProxyMode)

- 默认使用AnnotationBeanNameGenerator.generateBeanName获取bean的名称

 ①取类上的注解@Component || 继承Component|| ManagedBean ||Named的value值,如果为String类型直接返回

 ②当①返回空时,使用短类名

  - 使用AnnotationConfigUtils.processCommonDefinitionAnnotations(abd)解析获取@Lazy、Primary、DependsOn、Role、 Description设置到abd中

  - 使用参数中BeanDefinitionCustomizer处理一下abd

  - 使用BeanDefinitionHolder封装好abd、beanName

  - 使用AnnotationConfigUtils.applyScopedProxyMode进行是否代理的ScopedProxyMode的处理

    是话会创建一个代理类的BeanDefinitionHolder,底层封装了原BeanDefinitionHolder

  - 注册进入工厂的定义表中,registry.registerBeanDefinition


public class AnnotatedBeanDefinitionReader {

    private final BeanDefinitionRegistry registry;
    private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
    private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
    private ConditionEvaluator conditionEvaluator;


    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        //context带过来的BeanDefinitionRegistry注册表
        this.registry = registry;
        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        //注册必要的后置处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

    //核心方法:开始注册配置类
    public void register(Class<?>... componentClasses) {
        for (Class<?> componentClass : componentClasses) {
            registerBean(componentClass);
        }
    }
    public void registerBean(Class<?> beanClass) {
        doRegisterBean(beanClass, null, null, null, null);
    }
    private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
                                    @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
                                    @Nullable BeanDefinitionCustomizer[] customizers) {

        //先创建BeanDefinition,设置好属性,如beanClassScopePrimaryLazy
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }
        abd.setInstanceSupplier(supplier);
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        if (qualifiers != null) {
            for (Class<? extends Annotation> qualifier : qualifiers) {
                if (Primary.class == qualifier) {
                    abd.setPrimary(true);
                }
                else if (Lazy.class == qualifier) {
                    abd.setLazyInit(true);
                }
                else {
                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                }
            }
        }
        //使用BeanDefinitionCustomizer处理一下
        if (customizers != null) {
            for (BeanDefinitionCustomizer customizer : customizers) {
                customizer.customize(abd);
            }
        }
        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        //注册到容器的BeanDefinitionMap
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }
    
}

        

SpringBoot默认上下文—notationConfigServletWebServerApplicationContext

类图

WebApplicationContextConfigurableWebApplicationContext接口

* WebApplicationContext 接口

    - 增加一个接口方法ServletContext getServletContext():返回一个web用于上下文,其典型实现类为ApplicationContext,底层基于StandardContext

    - 一些常量

* ConfigurableWebApplicationContext接口

   - 继承自WebApplicationContext和ConfigurableApplicationContext,提供了web应用上下文的可配置的能力。

   - 可配置web应用上下文的ServletContext、ServletConfig、Namespace、上下文的配置文件位置


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();

}


public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {


   // 设置web应用上下文的ServletContext
   void setServletContext(@Nullable ServletContext servletContext);
   
   // 设置/获取web应用上下文的ServletConfig
   void setServletConfig(@Nullable ServletConfig servletConfig);
   ServletConfig getServletConfig();
   
   // 设置/获取web应用上下文的命名空间,标志当前的web应用上下文
   void setNamespace(@Nullable String namespace);
   String getNamespace();
   
   // 以初始化参数的形式设置web应用上下文的配置文件位置
   void setConfigLocation(String configLocation);
   void setConfigLocations(String... configLocations);
   String[] getConfigLocations();

}

WebServerApplicationContext和ConfigurableWebServerApplicationContext接口

* WebServerApplicationContext接口

  获取一个WebServer服务器对象、服务器对象的命名空间

* ConfigurableWebServerApplicationContext接口

  提供服务器对象的命名空间的设置


public interface WebServerApplicationContext extends ApplicationContext {

   //获取一个WebServer服务器对象,如内嵌的Tomcat服务器
   WebServer getWebServer();

   // 获取当前服务器对象的命名空间,即标识
   String getServerNamespace();
   static boolean hasServerNamespace(ApplicationContext context, String serverNamespace) {
      return (context instanceof WebServerApplicationContext) && ObjectUtils
            .nullSafeEquals(((WebServerApplicationContext) context).getServerNamespace(), serverNamespace);
   }

}

 
public interface ConfigurableWebServerApplicationContext
      extends ConfigurableApplicationContext, WebServerApplicationContext {

   //设置当前服务器对象的命名空间,即标识
   void setServerNamespace(String serverNamespace);

}

GenericWebApplicationContext

* 作用

继承GenericApplicationContext,在GenericApplicationContext基础上这种一个指定的web应用上下文ServletContext ,以及一些初始化动作

* 设置了一个核心成员ServletContext servletContext表示一个web应用上下文

  默认的实现是ApplicationContext类,底层封装了Tomcat的StardardContext

* 重写父类的createEnvironment方法

  使用StandardServletEnvironment对象作为容器的环境组件 

* 实现容器刷新流程AbstractApplicationContext.refresh中的两个模板方法,对工厂对象进行自定义处理

  ①postProcessBeanFactory方法,对工厂对象进行自定义处理

      - 添加一个bean后置处理器ServletContextAwareProcessor,在bean初始化前postProcessBeforeInitialzation()方法给bean注入当前的servletContext

   - 给bean工厂注册scope存储请求属性集合,调用beanFactory.registerScope三个范围的对象Request/Session/appScope(基于底层request/servletContext的attribute变量)

      - 在容器注册一些类型的指定依赖类型,如beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory())

      - 向容器中注册本类的核心成员ServletContext servletContext以及其相关的信息,交于容器管理

servletContext、servletConfig,contextParameters(ApplicationContext和servletConfig的getInitParameterNames初始配置信息)、contextAttributes(ApplicationContext中getAttributeNames的变量),调用bean工厂的registerSingleton的管理外部对象

if (servletContext != null && !bf.containsBean("servletContext")) {
            bf.registerSingleton("servletContext", servletContext);
        }

②initPropertySources方法,为prepareRefresh做刷新的准备的第一步,对ConfigurableEnvironment进行PropertySources的初始化设置

  基于servletContext.getInitParameterNames()封装了PropertySources


public class GenericWebApplicationContext extends GenericApplicationContext
      implements ConfigurableWebApplicationContext, ThemeSource {

   @Nullable
   private ServletContext servletContext;

   @Nullable
   private ThemeSource themeSource;

   public GenericWebApplicationContext(DefaultListableBeanFactory beanFactory, ServletContext servletContext) {
      super(beanFactory);
      this.servletContext = servletContext;
   }


   //主要处理了ServletContext servletContext的设置
   @Override
   public void setServletContext(@Nullable ServletContext servletContext) {
      this.servletContext = servletContext;
   }
   public ServletContext getServletContext() {
      return this.servletContext;
   }

   @Override
   public String getApplicationName() {
      return (this.servletContext != null ? this.servletContext.getContextPath() : "");
   }

   //创建一个新的ConfigurableEnvironment environment
   @Override
   protected ConfigurableEnvironment createEnvironment() {
      return new StandardServletEnvironment();
   }

   //实现容器刷新流程中的AbstractApplicationContext.postProcessBeanFactory,对工厂对象进行自定义处理
   @Override
   protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      if (this.servletContext != null) {
         //使用BeanPostProcessor,在bean初始化给bean注入当前的servletContext
         beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
         beanFactory.ignoreDependencyInterface(ServletContextAware.class);
      }
      //bean工厂注册scope存储,即registerScope
      /*
      * beanFactory.registerScope(SCOPE_REQUEST, new RequestScope()); 基于底层this.request.getAttribute
      beanFactory.registerScope(SCOPE_SESSION, new SessionScope());基于底层this.request.session.getAttribute
      beanFactory.registerScope(SCOPE_APPLICATION, appScope);基于底层tthis.servletContext.setAttribute
      *
      * */
      WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
      //向容器中注册:servletContextservletConfig(若存在),parameterMapApplicationparameters的变量以及servletConfigservlet的初始配置信息)
      WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
   }

   //实现容器刷新流程中的AbstractApplicationContext.initPropertySources,对ConfigurableEnvironment进行PropertySources的初始化设置
   //基于servletContext.getInitParameterNames()封装了PropertySources
   @Override
   protected void initPropertySources() {
      ConfigurableEnvironment env = getEnvironment();
      if (env instanceof ConfigurableWebEnvironment) {
         ((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
      }
   }


   //基于ServletContext.resource作为根目录的资源对象
   @Override
   protected Resource getResourceByPath(String path) {
      Assert.state(this.servletContext != null, "No ServletContext available");
      return new ServletContextResource(this.servletContext, path);
   }

   @Override
   protected ResourcePatternResolver getResourcePatternResolver() {
      return new ServletContextResourcePatternResolver(this);
   }

   @Override
   protected void onRefresh() {
      this.themeSource = UiApplicationContextUtils.initThemeSource(this);
   }
   @Override
   @Nullable
   public Theme getTheme(String themeName) {
      Assert.state(this.themeSource != null, "No ThemeSource available");
      return this.themeSource.getTheme(themeName);
   }


   // ---------------------------------------------------------------------
   // 如下方法不实现或者抛出异常
   // ---------------------------------------------------------------------

   @Override
   public void setServletConfig(@Nullable ServletConfig servletConfig) {}
   @Override
   @Nullable
   public ServletConfig getServletConfig() {throw new UnsupportedOperationException();}
   @Override
   public void setNamespace(@Nullable String namespace) {}
   @Override
   @Nullable
   public String getNamespace() {throw new UnsupportedOperationException();}
   @Override
   public void setConfigLocation(String configLocation) {
      if (StringUtils.hasText(configLocation)) {
         throw new UnsupportedOperationException(;
      }
   }
   @Override
   public void setConfigLocations(String... configLocations) {
      if (!ObjectUtils.isEmpty(configLocations)) {
         throw new UnsupportedOperationException();
      }
   }
   @Override
   public String[] getConfigLocations() {throw new UnsupportedOperationException();}

//
}

ServletWebServerApplicationContext

1、继承GenericWebApplicationContext,说明服务器上下文和应用上下文是一一对应,一套的,即时不同ServletWebServerApplicationContext上下文底层可能会使用同一个StandardServer

2、设置了核心变量的 WebServer webServer:表示一个服务器对象,如内嵌的TomcatWebServer服务器对象,底层对应StandardServer,StandardServer会绑定一个StandardService;StandardService会关联Connector、Container,最终关联一个StandardContext

3、设置一个ServletConfig 变量:表示一个servlet配置类,这是一个特殊的servlet对象,是本ServletWebServerApplicationContext内部调用的

4、覆盖了刷新流程AbstractApplicationContext.refresh

  当容器刷新失败时,需要关闭创建的webServer.stop()

5、覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法postProcessBeanFactory,

    ①WebApplicationContextServletContextAwareProcessor(this)会继承GenericWebApplicationContext中的ServletContextAwareProcessor,

所以这里不调用super.postProcessBeanFactory也没关系,会在postProcessBeforeInitialization给bean赋值ServletContext/ServletConfig,

WebApplicationContextServletContextAwareProcessor(this)使得getServletContext/getServletConfig优先从当前类获取,否则取super.getServletContext(),

当前类ServletWebServerApplicationContext this的getServletContext/getServletConfig返回的值,是在onRefresh()阶段启动WebServer赋值的

   ②registerWebApplicationScopes,注册3个领域的XXXscope对象

*6、(核心实现)覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法,在bean工厂做好准备时候会调用onRefresh抽象模板方法,(步骤在实例化bean之前);这里创建并启动一个完整的WebServer并启动服务器监听

   例如返回TomcatWebServer底层对应StandardServer,创建流程如下

    ①会创建StandardServer绑定一个StandardService,关联新建的Connector、Container

   ②在新建一个TomcatEmbeddedContext(继承standardContext)作为GenericWebApplicationContext所需的ServletContext ,配置Context的path、DosBae、Loader、valve、MimeMapping、注册ServletContextInitializer(这里会收集ServletContextInitialize类型的对象,例如Aopol配置的文件内容可以在这里进行拉去,并注入到环境对象Eviroment中)、addLifecycleListener、执行customizer.customize(context)等

   ③Host.addChild(context),执行StandardServer.start()启动服务器,会一路调用到StandardContext.startInternal()

     其中Initializer的onStartup是在StandardContext.startInternal()里面执行的,这时就会向Context注册Servlet、Filter、Listener,之后会执行loadOnStartup会载入Servlet

public class ServletWebServerApplicationContext extends GenericWebApplicationContext
      implements ConfigurableWebServerApplicationContext {

   private static final Log logger = LogFactory.getLog(ServletWebServerApplicationContextx.class);

   public static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet";

   //表示一个服务器对象,如内嵌的TomcatWebServer服务器对象,底层对应StandardServer
   //StandardServer会绑定一个StandardService
   //StandardService会关联ConnectorContainer,最终关联一个StandardContext
   private volatile WebServer webServer;

   private ServletConfig servletConfig;

   private String serverNamespace;


   public ServletWebServerApplicationContextx(DefaultListableBeanFactory beanFactory) {
      super(beanFactory);
   }

   //覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法,
   //WebApplicationContextServletContextAwareProcessor会继承GenericWebApplicationContext中的ServletContextAwareProcessor,所以这里不调用super.postProcessBeanFactory也没关系
   //WebApplicationContextServletContextAwareProcessor写了其getServletContext/getServletConfig优先从当前类获取
   //registerWebApplicationScopes,注册3个领域的XXXscope对象
   @Override
   protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
      beanFactory.ignoreDependencyInterface(ServletContextAware.class);
      registerWebApplicationScopes();
   }

   //覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法,
   //当容器刷新失败时,需要关闭创建的webServer
   @Override
   public final void refresh() throws BeansException, IllegalStateException {
      try {
         super.refresh();
      }
      catch (RuntimeException ex) {
         WebServer webServer = this.webServer;
         if (webServer != null) {
            webServer.stop();
         }
         throw ex;
      }
   }

   //覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法,
   // bean工厂做好准备时候会调用,这里创建并启动一个完整的WebServer
   @Override
   protected void onRefresh() {
      super.onRefresh();
      try {
         //创建并启动一个完整的WebServer
         createWebServer();
      }
      catch (Throwable ex) {
         throw new ApplicationContextException("Unable to start web server", ex);
      }
   }
   private void createWebServer() {
      WebServer webServer = this.webServer;
      ServletContext servletContext = getServletContext();
      if (webServer == null && servletContext == null) {
         //TomcatServletWebServerFactory
         ServletWebServerFactory factory = getWebServerFactory();
         //例如返回TomcatWebServer底层对应StandardServer
         //会创建StandardServer会绑定一个StandardService,关联新建的ConnectorContainer(直到Engine这一步)
         //在新建一个TomcatEmbeddedContext(继承standardContext),配置ContextpathDosBaeLoadervalveMimeMapping
         //注册ServletContextInitializeraddLifecycleListener、执行customizer.customize(context)
         //最后Host.addChild(context),执行StandardServer.start()
         //其中InitializeronStartup是在StandardContext.startInternal()里面执行的
         //这时就会向Context注册ServletFilterListener,之后会执行loadOnStartup会载入Servlet
         this.webServer = factory.getWebServer(getSelfInitializer());
         getBeanFactory().registerSingleton("webServerGracefulShutdown",new WebServerGracefulShutdownLifecycle(this.webServer));
         getBeanFactory().registerSingleton("webServerStartStop",new WebServerStartStopLifecycle(this, this.webServer));
      }
      else if (servletContext != null) {
         try {
            getSelfInitializer().onStartup(servletContext);
         }
         catch (ServletException ex) {
            throw new ApplicationContextException("Cannot initialize servlet context", ex);
         }
      }
      initPropertySources();
   }



   //获取ServletContext初始化器
   private ServletContextInitializer getSelfInitializer() {
      return this::selfInitialize;
   }
   //注意,这个方法会作为函数指针传递为TomcatEmbeddedContext
   private void selfInitialize(ServletContext servletContext) throws ServletException {
      //servletContext设置到父类的成员中
      prepareWebApplicationContext(servletContext);
      //创建ServletContextScope
      registerApplicationScope(servletContext);
      //向容器中注册:servletContextservletConfig(若存在),parameterMapApplicationContextparameters的变量以及servletConfigservlet的初始配置信息)
      WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
      //容器中创建中实现了ServletContextInitializer接口的bean,例如ServletRegistrationBean(调用其onStartupServletContext中注册ServletFilterListener
      //容器中创建中ServletFilter类型,转为对应的ServletRegistrationBean
      //执行所有收集到的ServletContextInitializerBeansonStartup
      for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
         beans.onStartup(servletContext);
      }
   }


   @Override
   protected Resource getResourceByPath(String path) {
      if (getServletContext() == null) {
         return new ClassPathContextResource(path, getClassLoader());
      }
      return new ServletContextResource(getServletContext(), path);
   }

   @Override
   public String getServerNamespace() {
      return this.serverNamespace;
   }
   @Override
   public void setServerNamespace(String serverNamespace) {
      this.serverNamespace = serverNamespace;
   }
   @Override
   public void setServletConfig(ServletConfig servletConfig) {
      this.servletConfig = servletConfig;
   }
   @Override
   public ServletConfig getServletConfig() {
      return this.servletConfig;
   }
   @Override
   public WebServer getWebServer() {
      return this.webServer;
   }



}

AnnotationConfigServletWebServerApplicationContext

* 支持指定注解配置类进行配置的ServletWebServerApplicationContext对象,是Springboot默认创建的上下文

* 覆盖了刷新流程AbstractApplicationContext.refresh中的模板方法postProcessBeanFactory,对工厂对象进行自定义处理

基于AnnotatedBeanDefinitionReader或者ClassPathBeanDefinitionScanner对指定的组件类,封装为BeanDefinition后注册到bean定义表中

*  AnnotatedBeanDefinitionReader其构造方法中AnnotationConfigUtils.registerAnnotationConfigProcessors

会注册必要的后置处理器,如解析@Configuration,@Autowrite的后置处理类:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等

* 为reader、scanner设置environment、beanNameGenerator和scopeMetadataResolver

public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
        implements AnnotationConfigRegistry {

    private final AnnotatedBeanDefinitionReader reader;
    private final ClassPathBeanDefinitionScanner scanner;
    private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();
    private String[] basePackages;

    //构造方法
    public AnnotationConfigServletWebServerApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    public AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory) {
        super(beanFactory);
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

    public AnnotationConfigServletWebServerApplicationContext(Class<?>... annotatedClasses) {
        this();
        //添加进annotatedClasses变量中
        register(annotatedClasses);
        refresh();
    }
    public AnnotationConfigServletWebServerApplicationContext(String... basePackages) {
        this();
        //添加进basePackages变量中
        scan(basePackages);
        refresh();
    }


    @Override
    protected void prepareRefresh() {
        this.scanner.clearCache();
        super.prepareRefresh();
    }

    //使用scanner或者reader
    @Override
    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()) {
            //把配置类的信息封装为对的BeanDefinition后注册到bean定义表中
            this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
        }
    }


    //readerscanner设置environmentbeanNameGeneratorscopeMetadataResolver
    @Override
    public void setEnvironment(ConfigurableEnvironment environment) {
        super.setEnvironment(environment);
        this.reader.setEnvironment(environment);
        this.scanner.setEnvironment(environment);
    }
    public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
        this.reader.setBeanNameGenerator(beanNameGenerator);
        this.scanner.setBeanNameGenerator(beanNameGenerator);
        getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
    }
    public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
        this.reader.setScopeMetadataResolver(scopeMetadataResolver);
        this.scanner.setScopeMetadataResolver(scopeMetadataResolver);
    }


    //
}

更多推荐