【Spring源码分析】13-DispatcherServlet中WebApplicationContext启动过程

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取10G资料包与项目实战视频资料

DispatcherServlet中WebApplicationContext的启动在父类FrameworkServlet的configureAndRefreshWebApplicationContext()方法中,其中WebApplicationContext的具体子类是AnnotationConfigWebApplicationContext。下图为ApplicationContext的继承结构。

20191017100333\_1.png

    protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
       if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
          // The application context id is still set to its original default value
          // -> assign a more useful id based on available information
          if (this.contextId != null) {
             wac.setId(this.contextId);
          }
          else {
             // Generate default id...
             wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
                   ObjectUtils.getDisplayString(getServletContext().getContextPath()) + '/' + getServletName());
          }
       }

       wac.setServletContext(getServletContext());
       wac.setServletConfig(getServletConfig());
       wac.setNamespace(getNamespace());
       wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));

       // The wac environment's #initPropertySources will be called in any case when the context
       // is refreshed; do it eagerly here to ensure servlet property sources are in place for
       // use in any post-processing or initialization that occurs below prior to #refresh
       ConfigurableEnvironment env = wac.getEnvironment();
       if (env instanceof ConfigurableWebEnvironment) {
          ((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
       }

       postProcessWebApplicationContext(wac);
       applyInitializers(wac);
       wac.refresh();
    }

ContextRefreshListener是FrameworkServlet的一个内部类,调用本实例(也就是DispatcherServlet)的onApplicationEvent()方法。

    private class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
       @Override
       public void onApplicationEvent(ContextRefreshedEvent event) {
          FrameworkServlet.this.onApplicationEvent(event);
       }
    }
    public void onApplicationEvent(ContextRefreshedEvent event) {
       this.refreshEventReceived = true;
       onRefresh(event.getApplicationContext());
    }
    @Override
    protected void onRefresh(ApplicationContext context) {
       initStrategies(context);
    }

initStrategies()在Spring MVC中在分析,这里知道是在什么地方注册的回调即可(finishRefresh()中会发布ContextRefreshedEvent事件)。

postProcessWebApplicationContext()为一个空实现,子类可以覆盖此方法,用于在ConfigurableWebApplicationContext刷新前对它进行一些操作。

applyInitializers()方法用于执行注册到contextInitializers中的ApplicationContextInitializer对象,执行顺序就是 AnnotationAwareOrderComparator的排序规则,优先级如下,其中order值越小代表优先级越高。

    实现PriorityOrdered接口>实现Ordered接口>被标记@Order或@Priority
    protected void applyInitializers(ConfigurableApplicationContext wac) {
       String globalClassNames = getServletContext().getInitParameter(ContextLoader.GLOBAL_INITIALIZER_CLASSES_PARAM);
       if (globalClassNames != null) {
          for (String className : StringUtils.tokenizeToStringArray(globalClassNames, INIT_PARAM_DELIMITERS)) {
             this.contextInitializers.add(loadInitializer(className, wac));
          }
       }

       if (this.contextInitializerClasses != null) {
          for (String className : StringUtils.tokenizeToStringArray(this.contextInitializerClasses, INIT_PARAM_DELIMITERS)) {
             this.contextInitializers.add(loadInitializer(className, wac));
          }
       }

       AnnotationAwareOrderComparator.sort(this.contextInitializers);
       for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : this.contextInitializers) {
          initializer.initialize(wac);
       }
    }

Spring核心框架中没有提供具体的ApplicationContextInitializer实现类,而Spring Boot提供了一系列实现如下,介绍Spring Boot时在详细介绍。

20191017100333\_2.png

refresh()是ApplicationContext启动的入口方法,作为一个模板方法被定义在了AbstractApplicationContext中,由子类决定具体方法的行为。

    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          // Prepare this context for refreshing.
          prepareRefresh();

          // Tell the subclass to refresh the internal bean factory.
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

          // Prepare the bean factory for use in this context.
          prepareBeanFactory(beanFactory);

          try {
             // Allows post-processing of the bean factory in context subclasses.
             postProcessBeanFactory(beanFactory);

             // Invoke factory processors registered as beans in the context.
             invokeBeanFactoryPostProcessors(beanFactory);

             // Register bean processors that intercept bean creation.
             registerBeanPostProcessors(beanFactory);

             // Initialize message source for this context.
             initMessageSource();

             // Initialize event multicaster for this context.
             initApplicationEventMulticaster();

             // Initialize other special beans in specific context subclasses.
             onRefresh();

             // Check for listener beans and register them.
             registerListeners();

             // Instantiate all remaining (non-lazy-init) singletons.
             finishBeanFactoryInitialization(beanFactory);

             // Last step: publish corresponding event.
             finishRefresh();
          }

          catch (BeansException ex) {
             if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                      "cancelling refresh attempt: " + ex);
             }

             // Destroy already created singletons to avoid dangling resources.
             destroyBeans();

             // Reset 'active' flag.
             cancelRefresh(ex);

             // Propagate exception to caller.
             throw ex;
          }

          finally {
             // Reset common introspection caches in Spring's core, since we
             // might not ever need metadata for singleton beans anymore...
             resetCommonCaches();
          }
       }
    }

1.prepareRefresh()在启动容器前做一些准备工作。

    protected void prepareRefresh() {
       this.startupDate = System.currentTimeMillis();
       this.closed.set(false);
       this.active.set(true);

       if (logger.isInfoEnabled()) {
          logger.info("Refreshing " + this);
       }

       // Initialize any placeholder property sources in the context environment
       initPropertySources();//这步在FrameworkServlet中已经做过,对于WebApplicationContext
       // Validate that all properties marked as required are resolvable
       // see ConfigurablePropertyResolver#setRequiredProperties
       getEnvironment().validateRequiredProperties();

       // Allow for the collection of early ApplicationEvents,
       // to be published once the multicaster is available...
       this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
    }

2.obtainFreshBeanFactory()创建一个BeanFactory,一般是DefaultListableBeanFactory。

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
       refreshBeanFactory();
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       if (logger.isDebugEnabled()) {
          logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
       }
       return beanFactory;
    }
    @Override
    protected final void refreshBeanFactory() throws BeansException {
       if (hasBeanFactory()) {
          destroyBeans();
          closeBeanFactory();
       }
       try {
          DefaultListableBeanFactory beanFactory = createBeanFactory();
          beanFactory.setSerializationId(getId());
          customizeBeanFactory(beanFactory);
          loadBeanDefinitions(beanFactory);
          synchronized (this.beanFactoryMonitor) {
             this.beanFactory = beanFactory;
          }
       }
       catch (IOException ex) {
          throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
       }
    }
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
       if (this.allowBeanDefinitionOverriding != null) {
          beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
       }
       if (this.allowCircularReferences != null) {
          beanFactory.setAllowCircularReferences(this.allowCircularReferences);
       }
    }

2.1.loadBeanDefinitions()方法用来加载并解析Bean为BeanDefinition。

    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
       AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory);
       ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory);

       BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
       if (beanNameGenerator != null) {
          reader.setBeanNameGenerator(beanNameGenerator);
          scanner.setBeanNameGenerator(beanNameGenerator);
          beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
       }

       ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
       if (scopeMetadataResolver != null) {
          reader.setScopeMetadataResolver(scopeMetadataResolver);
          scanner.setScopeMetadataResolver(scopeMetadataResolver);
       }

       if (!this.annotatedClasses.isEmpty()) {
          if (logger.isInfoEnabled()) {
             logger.info("Registering annotated classes: [" +
                   StringUtils.collectionToCommaDelimitedString(this.annotatedClasses) + "]");
          }
          reader.register(this.annotatedClasses.toArray(new Class<?>[this.annotatedClasses.size()]));
       }

       if (!this.basePackages.isEmpty()) {
          if (logger.isInfoEnabled()) {
             logger.info("Scanning base packages: [" +
                   StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]");
          }
          scanner.scan(this.basePackages.toArray(new String[this.basePackages.size()]));
       }

       String[] configLocations = getConfigLocations();
       if (configLocations != null) {
          for (String configLocation : configLocations) {
             try {
                Class<?> clazz = getClassLoader().loadClass(configLocation);
                if (logger.isInfoEnabled()) {
                   logger.info("Successfully resolved class for [" + configLocation + "]");
                }
                reader.register(clazz);
             }
             catch (ClassNotFoundException ex) {
                if (logger.isDebugEnabled()) {
                   logger.debug("Could not load class for config location [" + configLocation +
                         "] - trying package scan. " + ex);
                }
                int count = scanner.scan(configLocation);
                if (logger.isInfoEnabled()) {
                   if (count == 0) {
                      logger.info("No annotated classes found for specified class/package [" + configLocation + "]");
                   }
                   else {
                      logger.info("Found " + count + " annotated classes in package [" + configLocation + "]");
                   }
                }
             }
          }
       }
    }

AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner分别用来解析指定的Class和指定包下的Class为BeanDefinition。

    protected AnnotatedBeanDefinitionReader getAnnotatedBeanDefinitionReader(DefaultListableBeanFactory beanFactory) {
       return new AnnotatedBeanDefinitionReader(beanFactory, getEnvironment());
    }
    protected ClassPathBeanDefinitionScanner getClassPathBeanDefinitionScanner(DefaultListableBeanFactory beanFactory) {
       return new ClassPathBeanDefinitionScanner(beanFactory, true, getEnvironment());
    }

2.1.1.AnnotatedBeanDefinitionReader

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
       Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
       Assert.notNull(environment, "Environment must not be null");
       this.registry = registry;
       this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
       AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

ConditionEvaluator内部使用类,用来解析@Conditional注解。

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)为BeanFactory进行一些配置,主要是注册一些框架级别的BeanFactoryPostProcessor,这些BeanFactoryPostProcessor都非常重要,以后会进行单独说明。

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
          BeanDefinitionRegistry registry, Object source) {

       DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
       if (beanFactory != null) {
          if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
             beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
          }
          if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
             beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
          }
       }

       Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);

       if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
       }

       if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
       }

       if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
       }

       // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
       if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
       }

       // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
       if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition();
          try {
             def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                   AnnotationConfigUtils.class.getClassLoader()));
          }
          catch (ClassNotFoundException ex) {
             throw new IllegalStateException(
                   "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
          }
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
       }

       if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
       }
       if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
          RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
          def.setSource(source);
          beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
       }

       return beanDefs;
    }

之后会调用registerBean()方法从给定的Class上面的注解上推导出BeanDefinition。

     
    public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
       AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
       //不满足@Conditional注解value指定的实现Condition接口的实现类则跳过
       if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
          return;
       }
       //默认使用AnnotationScopeMetadataResolver从@Scope得到scopeName(默认singleton)和scopedProxyMode(默认ScopedProxyMode.NO)
       ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
       abd.setScope(scopeMetadata.getScopeName());
       String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
       //根据注解@Lazy,@Primary,@DependsOn,@Role,@Description设置BeanDefinition相应的属性
       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));
             }
          }
       }

       BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
       //如果是ScopedProxyMode.TARGET_CLASS,使用ScopedProxyCreator.createScopedProxy()新建一个BeanDefinition替换原有的
       //新的beanClass为ScopedProxyFactoryBean
       definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
       BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }

2.1.2.ClassPathBeanDefinitionScanner

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
          Environment environment, ResourceLoader resourceLoader) {
       Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
       this.registry = registry;

       if (useDefaultFilters) {
          registerDefaultFilters();
       }
       setEnvironment(environment);
       setResourceLoader(resourceLoader);
    }
    protected void registerDefaultFilters() {
       this.includeFilters.add(new AnnotationTypeFilter(Component.class));
       ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
       try {
          this.includeFilters.add(new AnnotationTypeFilter(
                ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
          logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
       }
       catch (ClassNotFoundException ex) {
          // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
       }
       try {
          this.includeFilters.add(new AnnotationTypeFilter(
                ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
          logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
       }
       catch (ClassNotFoundException ex) {
          // JSR-330 API not available - simply skip.
       }
    }

添加AnnotationTypeFilter到includeFilters,代表只有被includeFilters内匹配的注解才可以被扫描解析,这里默认会对标有@Component,@ManagedBean,@Named注解的类进行解析。

setResourceLoader()被定义在父类ClassPathScanningCandidateComponentProvider中,除了设置resourceLoader外还新建了两个对象。

    @Override
    public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
       this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
       this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
       this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
    }

Spring Framework 5 改进了扫描和识别组件的方法,使大型项目的性能得到提升。目前,扫描是在编译时执行的,而且向 META-INF/spring.components 文件中的索引文件添加了组件坐标。该索引是通过一个为项目定义的特定于平台的应用程序构建任务来生成的。标有来自 javax 包的注解的组件会添加到索引中,任何带 @Indexed 注解的类或接口都会添加到索引中。Spring 的传统类路径扫描方式没有删除,而是保留为一种后备选择。有许多针对大型代码库的明显性能优势,而托管许多 Spring 项目的服务器也会缩短启动时间。

    @Nullable
    private static CandidateComponentsIndex doLoadIndex(ClassLoader classLoader) {
       //在spring.properties中或系统属性中配置spring.index.ignore=true,可忽略这一组件的作用
       if (shouldIgnoreIndex) {
          return null;
       }
       try {
          Enumeration<URL> urls = classLoader.getResources(COMPONENTS_RESOURCE_LOCATION);
          if (!urls.hasMoreElements()) {
             return null;
          }
          List<Properties> result = new ArrayList<>();
          while (urls.hasMoreElements()) {
             URL url = urls.nextElement();
             Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
             result.add(properties);
          }
          if (logger.isDebugEnabled()) {
             logger.debug("Loaded " + result.size() + "] index(es)");
          }
          int totalCount = result.stream().mapToInt(Properties::size).sum();
          //将类路径下所有的META-INF/spring.components文件封装成List<Properties>传入构造方法中
          return (totalCount > 0 ? new CandidateComponentsIndex(result) : null);
       }
       catch (IOException ex) {
          throw new IllegalStateException("Unable to load indexes from location [" +
                COMPONENTS_RESOURCE_LOCATION + "]", ex);
       }
    }

CandidateComponentsIndex内部使用MultiValueMap<String, Entry>保存被标记@Indexed的注解与被此注解标记的类的映射,getCandidateTypes()方法从集合中取得指定包(包含子包)下面被stereotype注解标记的类。

    public class CandidateComponentsIndex {
       private final static AntPathMatcher pathMatcher = new AntPathMatcher(".");
       private final MultiValueMap<String, Entry> index;
       CandidateComponentsIndex(List<Properties> content) {
          this.index = parseIndex(content);
       }
       /**
        * Return the candidate types that are associated with the specified stereotype.
        * @param basePackage the package to check for candidates
        * @param stereotype the stereotype to use
        * @return the candidate types associated with the specified {@code stereotype}
        * or an empty set if none has been found for the specified {@code basePackage}
        */
       public Set<String> getCandidateTypes(String basePackage, String stereotype) {
          List<Entry> candidates = this.index.get(stereotype);
          if (candidates != null) {
             return candidates.parallelStream()
                   .filter(t -> t.match(basePackage))
                   .map(t -> t.type)
                   .collect(Collectors.toSet());
          }
          return Collections.emptySet();
       }

       private static MultiValueMap<String, Entry> parseIndex(List<Properties> content) {
          MultiValueMap<String, Entry> index = new LinkedMultiValueMap<>();
          for (Properties entry : content) {
             entry.forEach((type, values) -> {
                String[] stereotypes = ((String) values).split(",");
                for (String stereotype : stereotypes) {
                   index.add(stereotype, new Entry((String) type));
                }
             });
          }
          return index;
       }

       private static class Entry {
          private final String type;
          private final String packageName;
          Entry(String type) {
             this.type = type;
             this.packageName = ClassUtils.getPackageName(type);
          }
          public boolean match(String basePackage) {
             if (pathMatcher.isPattern(basePackage)) {
                return pathMatcher.match(basePackage, this.packageName);
             }
             else {
                return this.type.startsWith(basePackage);
             }
          }
       }
    }

下面再看ClassPathBeanDefinitionScanner的scan()方法,主要是调用了doScan()方法,找出指定包名下符合bean定义的BeanDefinition注册到容器中,具体下面看。

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
       Assert.notEmpty(basePackages, "At least one base package must be specified");
       Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
       for (String basePackage : basePackages) {
          Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
          for (BeanDefinition candidate : candidates) {
             ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
             candidate.setScope(scopeMetadata.getScopeName());
             String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
             if (candidate instanceof AbstractBeanDefinition) {
                postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
             }
             if (candidate instanceof AnnotatedBeanDefinition) {
                AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
             }
             if (checkCandidate(beanName, candidate)) {
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                definitionHolder =
                      AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                beanDefinitions.add(definitionHolder);
                registerBeanDefinition(definitionHolder, this.registry);
             }
          }
       }
       return beanDefinitions;
    }

findCandidateComponents()方法负责找出spring bean定义,if分支使用了上面讲到的CandidateComponentsIndex,else分支为包扫描方式。

    public Set<BeanDefinition> findCandidateComponents(String basePackage) {
       if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
          return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
       }
       else {
          return scanCandidateComponents(basePackage);
       }
    }

includeFilters中只要有一个AnnotationTypeFilter或AssignableTypeFilter的注解类型没有被@Indexed标记或不属于包javax.下面的都不会走if分支也就不会用到CandidateComponentsIndex。

    private boolean indexSupportsIncludeFilters() {
       for (TypeFilter includeFilter : this.includeFilters) {
          if (!indexSupportsIncludeFilter(includeFilter)) {
             return false;
          }
       }
       return true;
    }
    private boolean indexSupportsIncludeFilter(TypeFilter filter) {
       if (filter instanceof AnnotationTypeFilter) {
          Class<? extends Annotation> annotation = ((AnnotationTypeFilter) filter).getAnnotationType();
          return (AnnotationUtils.isAnnotationDeclaredLocally(Indexed.class, annotation) ||
                annotation.getName().startsWith("javax."));
       }
       if (filter instanceof AssignableTypeFilter) {
          Class<?> target = ((AssignableTypeFilter) filter).getTargetType();
          return AnnotationUtils.isAnnotationDeclaredLocally(Indexed.class, target);
       }
       return false;
    }

if分支中就是从META/spring.components索引文件中取出basePackage包下标有includeFilters中注解的类,isCandidateComponent()方法用来过滤此类是否可以作为BeanDefinition。isCandidateComponent()方法接收一个MetadataReader对象,该对象是由CachingMetadataReaderFactory根据bean的类名创建的一个SimpleMetadataReader实例,在构造方法内部使用了ClassReader用来解析class文件获取类的元数据信息。

    final class SimpleMetadataReader implements MetadataReader {
       private final Resource resource;
       private final ClassMetadata classMetadata;
       private final AnnotationMetadata annotationMetadata;
       SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException {
          InputStream is = new BufferedInputStream(resource.getInputStream());
          ClassReader classReader;
          try {
             classReader = new ClassReader(is);
          }
          catch (IllegalArgumentException ex) {
             throw new NestedIOException("ASM ClassReader failed to parse class file - " +
                   "probably due to a new Java class file version that isn't supported yet: " + resource, ex);
          }
          finally {
             is.close();
          }
          AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(classLoader);
          classReader.accept(visitor, ClassReader.SKIP_DEBUG);
          this.annotationMetadata = visitor;
          // (since AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor)
          this.classMetadata = visitor;
          this.resource = resource;
       }
       @Override
       public Resource getResource() {
          return this.resource;
       }
       @Override
       public ClassMetadata getClassMetadata() {
          return this.classMetadata;
       }
       @Override
       public AnnotationMetadata getAnnotationMetadata() {
          return this.annotationMetadata;
       }
    }

excludeFilters优先级高于includeFilters,通过includeFilters还需要ConditionEvaluator对条件的校验。

    protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
       for (TypeFilter tf : this.excludeFilters) {
          if (tf.match(metadataReader, getMetadataReaderFactory())) {
             return false;
          }
       }
       for (TypeFilter tf : this.includeFilters) {
          if (tf.match(metadataReader, getMetadataReaderFactory())) {
             return isConditionMatch(metadataReader);
          }
       }
       return false;
    }

之后创建一个AnnotatedGenericBeanDefinition对象,使用isCandidateComponent()重载方法在次判断是否符合Bean定义。

    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
       AnnotationMetadata metadata = beanDefinition.getMetadata();
       return (metadata.isIndependent() && (metadata.isConcrete() ||
             (metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
    }

判断是一个class是独立的,有两种情况:一.他是top-level的 二.他是nested class也就是静态内部类。

else分支遍历指定包下的所有类文件转换为MetadataReader对象,默认有@Component注解则认为符合bean的定义。

    private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
       Set<BeanDefinition> candidates = new LinkedHashSet<>();
       try {
          String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                resolveBasePackage(basePackage) + '/' + this.resourcePattern;
          Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
          boolean traceEnabled = logger.isTraceEnabled();
          boolean debugEnabled = logger.isDebugEnabled();
          for (Resource resource : resources) {
             if (traceEnabled) {
                logger.trace("Scanning " + resource);
             }
             if (resource.isReadable()) {
                try {
                   MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
                   if (isCandidateComponent(metadataReader)) {
                      ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                      sbd.setResource(resource);
                      sbd.setSource(resource);
                      if (isCandidateComponent(sbd)) {
                         if (debugEnabled) {
                            logger.debug("Identified candidate component class: " + resource);
                         }
                         candidates.add(sbd);
                      }
                      else {
                         if (debugEnabled) {
                            logger.debug("Ignored because not a concrete top-level class: " + resource);
                         }
                      }
                   }
                   else {
                      if (traceEnabled) {
                         logger.trace("Ignored because not matching any filter: " + resource);
                      }
                   }
                }
                catch (Throwable ex) {
                   throw new BeanDefinitionStoreException(
                         "Failed to read candidate component class: " + resource, ex);
                }
             }
             else {
                if (traceEnabled) {
                   logger.trace("Ignored because not readable: " + resource);
                }
             }
          }
       }
       catch (IOException ex) {
          throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
       }
       return candidates;
    }

3.prepareBeanFactory()为BeanFactory配置标准的上下文特征如post-processors。

     
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       // Tell the internal bean factory to use the context's class loader etc.
       beanFactory.setBeanClassLoader(getClassLoader());
       beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
       beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

       // Configure the bean factory with context callbacks.
       beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
       //下面6种类型autowire不会自动装配,因为ApplicationContextAwareProcessor会自动set相应的对象
       beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
       beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
       beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
       beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
       beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

       // BeanFactory interface not registered as resolvable type in a plain factory.
       // MessageSource registered (and found for autowiring) as a bean.
       beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
       beanFactory.registerResolvableDependency(ResourceLoader.class, this);
       beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
       beanFactory.registerResolvableDependency(ApplicationContext.class, this);

       // Register early post-processor for detecting inner beans as ApplicationListeners.
       beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

       // Detect a LoadTimeWeaver and prepare for weaving, if found.
       if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
          beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
          // Set a temporary ClassLoader for type matching.
          beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
       }

       // Register default environment beans.
       if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
          beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
       }
       if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
          beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
       }
       if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
          beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
       }
    }

4.postProcessBeanFactory()由子类AbstractRefreshableWebApplicationContext覆盖,添加与servletContext相关的bean。

    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
       beanFactory.ignoreDependencyInterface(ServletContextAware.class);
       beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
       //注册针对web环境的scope ("request", "session", "globalSession", "application")
       WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
       //注册ServletContext环境相关的单例
       WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
    }
    public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, ServletContext sc) {
       beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
       beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope(false));
       beanFactory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, new SessionScope(true));
       if (sc != null) {
          ServletContextScope appScope = new ServletContextScope(sc);
          beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
          // Register as ServletContext attribute, for ContextCleanupListener to detect it.
          sc.setAttribute(ServletContextScope.class.getName(), appScope);
       }

       beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
       beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
       beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
       beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
       if (jsfPresent) {
          FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
       }
    }
    public static void registerEnvironmentBeans(
          ConfigurableListableBeanFactory bf, ServletContext servletContext, ServletConfig servletConfig) {

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

       if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
          bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);
       }

       if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
          Map<String, String> parameterMap = new HashMap<String, String>();
          if (servletContext != null) {
             Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();
             while (paramNameEnum.hasMoreElements()) {
                String paramName = (String) paramNameEnum.nextElement();
                parameterMap.put(paramName, servletContext.getInitParameter(paramName));
             }
          }
          if (servletConfig != null) {
             Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();
             while (paramNameEnum.hasMoreElements()) {
                String paramName = (String) paramNameEnum.nextElement();
                parameterMap.put(paramName, servletConfig.getInitParameter(paramName));
             }
          }
          bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
                Collections.unmodifiableMap(parameterMap));
       }

       if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {
          Map<String, Object> attributeMap = new HashMap<String, Object>();
          if (servletContext != null) {
             Enumeration<?> attrNameEnum = servletContext.getAttributeNames();
             while (attrNameEnum.hasMoreElements()) {
                String attrName = (String) attrNameEnum.nextElement();
                attributeMap.put(attrName, servletContext.getAttribute(attrName));
             }
          }
          bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,
                Collections.unmodifiableMap(attributeMap));
       }
    }

5.invokeBeanFactoryPostProcessors()方法用来执行已经注册过的 BeanFactoryPostProcessor,许多核心注解处理器就在这个地方生效的,以后会单独讲解这些核心BeanFactoryPostProcessor。

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
       //核心方法
       PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

       // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
       // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
       if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
          beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
          beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
       }
    }

下面是PostProcessorRegistrationDelegate的代码,逐句分析一下。

    class PostProcessorRegistrationDelegate {
       public static void invokeBeanFactoryPostProcessors(
             ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

          // Invoke BeanDefinitionRegistryPostProcessors first, if any.
          //用来保存已从bean factory取出以bean定义方式注册的BeanFactoryPostProcessor的bean name
          Set<String> processedBeans = new HashSet<>();

          if (beanFactory instanceof BeanDefinitionRegistry) {
             BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
             //保存一般的BeanFactoryPostProcessor而非BeanDefinitionRegistryPostProcessor
             List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
             //保存特殊的BeanFactoryPostProcessor子类BeanDefinitionRegistryPostProcessor
             List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
             //优先处理已通过addBeanFactoryPostProcessor()方法添加好的BeanFactoryPostProcessor
             for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                //如果是BeanDefinitionRegistryPostProcessor直接调用其postProcessBeanDefinitionRegistry()方法并保存它
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                   BeanDefinitionRegistryPostProcessor registryProcessor =
                         (BeanDefinitionRegistryPostProcessor) postProcessor;
                   registryProcessor.postProcessBeanDefinitionRegistry(registry);
                   registryProcessors.add(registryProcessor);
                }
                else {
                   //普通BeanFactoryPostProcessor先不执行,保存下来后面同一执行
                   regularPostProcessors.add(postProcessor);
                }
             }

             // Do not initialize FactoryBeans here: We need to leave all regular beans
             // uninitialized to let the bean factory post-processors apply to them!
             // Separate between BeanDefinitionRegistryPostProcessors that implement
             // PriorityOrdered, Ordered, and the rest.
             List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

             // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
             //从bean定义方式中找出实现了接口PriorityOrdered的BeanDefinitionRegistryPostProcessor的bean实例,放入容器currentRegistryProcessors中
             String[] postProcessorNames =
                   beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
             for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                   currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                   processedBeans.add(ppName);
                }
             }
             //将bean定义形式的BeanDefinitionRegistryPostProcessor实例按已设置的dependencyComparator(AnnotationAwareOrderComparator.INSTANCE)排序,排序规则前面讲过
             sortPostProcessors(currentRegistryProcessors, beanFactory);
             registryProcessors.addAll(currentRegistryProcessors);
             //按照排序好的BeanDefinitionRegistryPostProcessor对象依次调用postProcessBeanDefinitionRegistry()方法
             invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
             currentRegistryProcessors.clear();

             // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
             //从bean定义方式中找出实现了接口Ordered的BeanDefinitionRegistryPostProcessor的bean实例,并且保证不能重复处理同一个对象
             postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
             for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                   currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                   processedBeans.add(ppName);
                }
             }
             sortPostProcessors(currentRegistryProcessors, beanFactory);
             registryProcessors.addAll(currentRegistryProcessors);
             invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
             //到此为止,Spring框架内置的与我们手动添加(包括addBeanFactoryPostProcessor和BeanDefinition形式)的BeanDefinitionRegistryPostProcessor已执行完毕
             currentRegistryProcessors.clear();

             // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
             // 由于registryProcessors中的BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()方法可能会动态的添加一些bean定义和BeanFactoryPostProcessor
             // 所以需要不断地从beanFactory中取出registryProcessors未保存的BeanDefinitionRegistryPostProcessor实例调用postProcessBeanDefinitionRegistry()方法
             // 直到beanFactory不再有新的BeanDefinitionRegistryPostProcessor实例出现
             boolean reiterate = true;
             while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                   if (!processedBeans.contains(ppName)) {
                      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                      processedBeans.add(ppName);
                      reiterate = true;
                   }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
             }

             // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
             // postProcessBeanDefinitionRegistry()方法全都执行完后,就可以执行BeanFactoryPostProcessor中的postProcessBeanFactory()方法了
             // BeanDefinitionRegistryPostProcessor优先执行于BeanFactoryPostProcessor
             invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
             invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
          }

          else {
             // Invoke factory processors registered with the context instance.
             invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
          }

          // Do not initialize FactoryBeans here: We need to leave all regular beans
          // uninitialized to let the bean factory post-processors apply to them!
          // 最后处理bean定义的BeanFactoryPostProcessor,优先级为:实现PriorityOrdered接口的 > 实现Ordered接口的 > 其他
          String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

          // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
          // Ordered, and the rest.
          List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
          List<String> orderedPostProcessorNames = new ArrayList<>();
          List<String> nonOrderedPostProcessorNames = new ArrayList<>();
          for (String ppName : postProcessorNames) {
             if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
             }
             else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
             }
             else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
             }
             else {
                nonOrderedPostProcessorNames.add(ppName);
             }
          }

          // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
          sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
          invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

          // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
          List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
          for (String postProcessorName : orderedPostProcessorNames) {
             orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
          }
          sortPostProcessors(orderedPostProcessors, beanFactory);
          invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

          // Finally, invoke all other BeanFactoryPostProcessors.
          List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
          for (String postProcessorName : nonOrderedPostProcessorNames) {
             nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
          }
          invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

          // Clear cached merged bean definitions since the post-processors might have
          // modified the original metadata, e.g. replacing placeholders in values...
          beanFactory.clearMetadataCache();
       }
    }

6.registerBeanPostProcessors()方法从bean factory中实例化BeanPostProcessor后注册。

    public static void registerBeanPostProcessors(
          ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

       String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

       // Register BeanPostProcessorChecker that logs an info message when
       // a bean is created during BeanPostProcessor instantiation, i.e. when
       // a bean is not eligible for getting processed by all BeanPostProcessors.
       int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
       // 如果一个bean实例化的时候不是所有BeanPostProcessor都被注册,这时BeanPostProcessorChecker会打印info级别的日志:
       // logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() + "] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)")
       beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

       // Separate between BeanPostProcessors that implement PriorityOrdered,Ordered, and the rest.
       // 处理区分优先级与BeanFactoryPostProcessor一样
       List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
       // 保存MergedBeanDefinitionPostProcessor实例并且最后注册
       List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
       List<String> orderedPostProcessorNames = new ArrayList<>();
       List<String> nonOrderedPostProcessorNames = new ArrayList<>();
       for (String ppName : postProcessorNames) {
          if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
             BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
             priorityOrderedPostProcessors.add(pp);
             if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
             }
          }
          else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
             orderedPostProcessorNames.add(ppName);
          }
          else {
             nonOrderedPostProcessorNames.add(ppName);
          }
       }

       // First, register the BeanPostProcessors that implement PriorityOrdered.
       sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

       // Next, register the BeanPostProcessors that implement Ordered.
       List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
       for (String ppName : orderedPostProcessorNames) {
          BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
          orderedPostProcessors.add(pp);
          if (pp instanceof MergedBeanDefinitionPostProcessor) {
             internalPostProcessors.add(pp);
          }
       }
       sortPostProcessors(orderedPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, orderedPostProcessors);

       // Now, register all regular BeanPostProcessors.
       List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
       for (String ppName : nonOrderedPostProcessorNames) {
          BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
          nonOrderedPostProcessors.add(pp);
          if (pp instanceof MergedBeanDefinitionPostProcessor) {
             internalPostProcessors.add(pp);
          }
       }
       registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

       // Finally, re-register all internal BeanPostProcessors.
       sortPostProcessors(internalPostProcessors, beanFactory);
       registerBeanPostProcessors(beanFactory, internalPostProcessors);

       // Re-register post-processor for detecting inner beans as ApplicationListeners,
       // moving it to the end of the processor chain (for picking up proxies etc).
       // ApplicationListenerDetector会将单例bean是ApplicationListener的加入applicationContext中
       // applicationContext.addApplicationListener((ApplicationListener<?>) bean)
       beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

7.initMessageSource()方法为容器中注册一个名为messageSource的 DelegatingMessageSource的bean用于i18n。

    protected void initMessageSource() {
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
          this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
          // Make MessageSource aware of parent MessageSource.
          if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
             HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
             if (hms.getParentMessageSource() == null) {
                // Only set parent context as parent MessageSource if no parent MessageSource
                // registered already.
                hms.setParentMessageSource(getInternalParentMessageSource());
             }
          }
          if (logger.isDebugEnabled()) {
             logger.debug("Using MessageSource [" + this.messageSource + "]");
          }
       }
       else {
          // Use empty MessageSource to be able to accept getMessage calls.
          DelegatingMessageSource dms = new DelegatingMessageSource();
          dms.setParentMessageSource(getInternalParentMessageSource());
          this.messageSource = dms;
          beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
          if (logger.isDebugEnabled()) {
             logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                   "': using default [" + this.messageSource + "]");
          }
       }
    }

8.initApplicationEventMulticaster()方法注册applicationEventMulticaster

    protected void initApplicationEventMulticaster() {
       ConfigurableListableBeanFactory beanFactory = getBeanFactory();
       if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
          this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
          if (logger.isDebugEnabled()) {
             logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
          }
       }
       else {
          this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
          beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
          if (logger.isDebugEnabled()) {
             logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                   APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                   "': using default [" + this.applicationEventMulticaster + "]");
          }
       }
    }

9.onRefresh()方法默认在AbstractRefreshableWebApplicationContext中注册一个名为themeSource的ResourceBundleThemeSource。

    public static ThemeSource initThemeSource(ApplicationContext context) {
       if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) {
          ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class);
          // Make ThemeSource aware of parent ThemeSource.
          if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) {
             HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource;
             if (hts.getParentThemeSource() == null) {
                // Only set parent context as parent ThemeSource if no parent ThemeSource
                // registered already.
                hts.setParentThemeSource((ThemeSource) context.getParent());
             }
          }
          if (logger.isDebugEnabled()) {
             logger.debug("Using ThemeSource [" + themeSource + "]");
          }
          return themeSource;
       }
       else {
          // Use default ThemeSource to be able to accept getTheme calls, either
          // delegating to parent context's default or to local ResourceBundleThemeSource.
          HierarchicalThemeSource themeSource = null;
          if (context.getParent() instanceof ThemeSource) {
             themeSource = new DelegatingThemeSource();
             themeSource.setParentThemeSource((ThemeSource) context.getParent());
          }
          else {
             themeSource = new ResourceBundleThemeSource();
          }
          if (logger.isDebugEnabled()) {
             logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME +
                   "': using default [" + themeSource + "]");
          }
          return themeSource;
       }
    }

10.registerListeners()方法将容器中的所有ApplicationListener添加到ApplicationEventMulticaster中以便所有ApplicationListener可以监听到消息。

    protected void registerListeners() {
       // Register statically specified listeners first.
       for (ApplicationListener<?> listener : getApplicationListeners()) {
          getApplicationEventMulticaster().addApplicationListener(listener);
       }

       // Do not initialize FactoryBeans here: We need to leave all regular beans
       // uninitialized to let post-processors apply to them!
       String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
       for (String listenerBeanName : listenerBeanNames) {
          getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
       }

       // Publish early application events now that we finally have a multicaster...
       Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
       this.earlyApplicationEvents = null;
       if (earlyEventsToProcess != null) {
          for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
             getApplicationEventMulticaster().multicastEvent(earlyEvent);
          }
       }
    }

11.finishBeanFactoryInitialization()方法主要是提前实例化单例对象。

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
       // Initialize conversion service for this context.
       if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
             beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
          beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
       }

       // Register a default embedded value resolver if no bean post-processor
       // (such as a PropertyPlaceholderConfigurer bean) registered any before:
       // at this point, primarily for resolution in annotation attribute values.
       if (!beanFactory.hasEmbeddedValueResolver()) {
          beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
             @Override
             public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
             }
          });
       }

       // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
       String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
       for (String weaverAwareName : weaverAwareNames) {
          getBean(weaverAwareName);
       }

       // Stop using the temporary ClassLoader for type matching.
       beanFactory.setTempClassLoader(null);

       // Allow for caching all bean definition metadata, not expecting further changes.
       beanFactory.freezeConfiguration();

       // Instantiate all remaining (non-lazy-init) singletons.
       beanFactory.preInstantiateSingletons();
    }
    public void preInstantiateSingletons() throws BeansException {
       if (this.logger.isDebugEnabled()) {
          this.logger.debug("Pre-instantiating singletons in " + this);
       }

       // Iterate over a copy to allow for init methods which in turn register new bean definitions.
       // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
       List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

       // Trigger initialization of all non-lazy singleton beans...
       for (String beanName : beanNames) {
          RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
          if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
             if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                   final FactoryBean<?> factory = (FactoryBean<?>) bean;
                   boolean isEagerInit;
                   if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                      isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                  ((SmartFactoryBean<?>) factory)::isEagerInit,
                            getAccessControlContext());
                   }
                   else {
                      isEagerInit = (factory instanceof SmartFactoryBean &&
                            ((SmartFactoryBean<?>) factory).isEagerInit());
                   }
                   if (isEagerInit) {
                      getBean(beanName);
                   }
                }
             }
             else {
                getBean(beanName);
             }
          }
       }

       // Trigger post-initialization callback for all applicable beans...
       for (String beanName : beanNames) {
          Object singletonInstance = getSingleton(beanName);
          if (singletonInstance instanceof SmartInitializingSingleton) {
             final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
             if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                   smartSingleton.afterSingletonsInstantiated();
                   return null;
                }, getAccessControlContext());
             }
             else {
                smartSingleton.afterSingletonsInstantiated();
             }
          }
       }
    }

12.finishRefresh()注册LifecycleProcessor,发布ContextRefreshedEvent。

    protected void finishRefresh() {
       // Initialize lifecycle processor for this context.
       initLifecycleProcessor();

       // Propagate refresh to lifecycle processor first.
       getLifecycleProcessor().onRefresh();

       // Publish the final event.
       publishEvent(new ContextRefreshedEvent(this));

       // Participate in LiveBeansView MBean, if active.
       LiveBeansView.registerApplicationContext(this);
    }

来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » 【Spring源码分析】13-DispatcherServlet中WebApplicationContext启动过程

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏