zoukankan      html  css  js  c++  java
  • new AnnotationConfigApplicationContext(MyBean.class)时,发生了什么?

     

    当我们run一段代码,像下面这样两行。spring究竟做了什么些,让整个容器准备就绪,交付给用户直接可用的各种特性。为了弄清楚,默默梳理记录下来。
    public static void main (String[] args) {
        AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext(MyBean.class);
        c.getBean(MyBean.class).getS();
    }


    首先来看下 Annotationconfigapplicationcontext 的uml图

    涉及到几个比较关键的类:GenericApplicationContext,AbstractApplicationContext,DefaultResourceLoader

    几个很重要的接口:ApplicationContext,ApplicationEventPubliser,BeanFactory,ListableBeanFactory,BeanDefinitionRegistory,ResourceLoader。好复杂是不是,没关系,先放一放。我们直接进入代码看看。

    第一步当然是构造函数,AnnotationConfigApplication的初始化必然会先初始化父类,看看GenericApplication和AbstractApplicationContext初始化做了些什么。

    0.AnnotationConfigApplication的构造函数。
    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
       this();
       register(annotatedClasses);
       refresh();
    }

    先看 this() :
    同时初始化了 AnnotationBeanDefinitionReader
    和 ClasspathBeanDefinitionScanner 这两个类各自去创建bean生成的环境。
    public AnnotationConfigApplicationContext() {
       this.reader = new AnnotatedBeanDefinitionReader(this);
       this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    进入:AnnotatedBeanDefinitionReader
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
       this(registry, getOrCreateEnvironment(registry));//构造了 StandardEnvironment 
    
    }

    进入:ClassPathBeanDefinitionScanner

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
       this(registry, true);
    }

    调用
    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
       this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
    }

    调用
    
    
    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
          Environment environment, ResourceLoader resourceLoader) {
    
       Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
       this.registry = registry;
    
       if (useDefaultFilters) {
          registerDefaultFilters();//注册默认的过滤器 包括 component,jsr-250的ManageBean,jsr-330的Named
       }
       setEnvironment(environment);
       setResourceLoader(resourceLoader);
    }
     
    
    
    /**
    * Register the default filter for {@link Component @Component}.
    * <p>This will implicitly register all annotations that have the
    * {@link Component @Component} meta-annotation including the
    * {@link Repository @Repository}, {@link Service @Service}, and
    * {@link Controller @Controller} stereotype annotations.
    * <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and
    * JSR-330's {@link javax.inject.Named} annotations, if available.
    *
    */
    @SuppressWarnings("unchecked")
    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.
    }
    }
     
    
    
    在看父类的构造函数。

    1.进入 GenericApplicationContext
    初始化了默认的beanfactory:DefaultListableBeanFactory
    public GenericApplicationContext() {
       this.beanFactory = new DefaultListableBeanFactory();}

     2.进入抽象类  AbstractApplicationContext

    先执行了静态块,目前还不知道干啥用的,从住上来看是为针对weblogic的补丁。
    static {
       // Eagerly load the ContextClosedEvent class to avoid weird classloader issues
       // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
       ContextClosedEvent.class.getName();
    }
    无参的构造函数。初始化了资源解析器。
    /**
     * Create a new AbstractApplicationContext with no parent.
     */
    public AbstractApplicationContext() {
       this.resourcePatternResolver = getResourcePatternResolver();
    }

    进到getResourcePatternResolver();
    protected ResourcePatternResolver getResourcePatternResolver() {
       return new PathMatchingResourcePatternResolver(this);
    }
    将 PathMatchingResourcePatternResolver 作为默认的资源解析器。(对于ResourceLoader spring也定义了一套比较复杂的规则,后面再讲)

    3.进到DefaultResourceLoader
    /**
     * Create a new DefaultResourceLoader.
     * <p>ClassLoader access will happen using the thread context class loader
     * at the time of this ResourceLoader's initialization.
     * @see java.lang.Thread#getContextClassLoader()
     */
    public DefaultResourceLoader() {
       this.classLoader = ClassUtils.getDefaultClassLoader();
    }

    进入ClassUtils中:

    public static ClassLoader getDefaultClassLoader() {
       ClassLoader cl = null;
       try {
          cl = Thread.currentThread().getContextClassLoader();
       }
       catch (Throwable ex) {
          // Cannot access thread context ClassLoader - falling back...
       }
       if (cl == null) {
          // No thread context class loader -> use class loader of this class.
          cl = ClassUtils.class.getClassLoader();
          if (cl == null) {
             // getClassLoader() returning null indicates the bootstrap ClassLoader
             try {
                cl = ClassLoader.getSystemClassLoader();
             }
             catch (Throwable ex) {
                // Cannot access system ClassLoader - oh well, maybe the caller can live with null...
             }
          }
       }
       return cl;
    }

    能看到spring给DefaultResourceLoader持有了classloader 线程上下文类加载器 -- 当前类的类加载器 -- 系统类加载器(Appclassloader)
    关于java的类加载器请拜读 深度好文: https://blog.csdn.net/javazejian/article/details/73413292



    到此为止,spring的准备工作做好了。
    1.GenericApplicationContext 创建了beanFactory -- DefaultListableBeanFactory
    2.AbstractApplicationContext 构建了ResourceLoader
    3.DefaultResourceLoader 准备好了ClassLoader
    4.AnnotationConfigApplication 准备好BeanFactory 的 AnnotationBeanDefinitionReader 和 ClassPathBeanDefinitionScanner
    5.AnnotationBeanDefinitionReader 准备好了conditionEvaluator 和 annotationprocessor
    6.ClassPathBeanDefinitionScanner 注册了需要扫描的注解 如component 以及之下的 service,repository,controller等
    7.DefaultListableBeanFactory 准备好了beanDefinitionMap存放 bean。
     

    再看
    register(annotatedClasses);方法

    ==调用==
    @SuppressWarnings("unchecked")
    public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
       AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
       if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {//跳过处理
          return;
       }
    
       ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//获取@scope注解
       abd.setScope(scopeMetadata.getScopeName());
       String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//取得bean名字
       AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);//处理Lazy primary等注解,仅仅是设置属性。
       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);
       definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//进入
       BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }
    static BeanDefinitionHolder applyScopedProxyMode(
          ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
    
       ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
       if (scopedProxyMode.equals(ScopedProxyMode.NO)) {//不需要代理直接返回
          return definition;
       }
       boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);//默认是cglib的方式代理
       return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
    }


    所以,register方法主要作用就是把bean上的注解扫描一遍。想是别名,懒加载,代理模式,scope等,将其注册到beanDefinitionRegistry(这个registry其实就是AnnotationConfigApplicationContext)中。


    接下来看重头戏refresh();方法,这是AbstractApplicationContext种定义的方法。所有的AbstractApplicationContext容器的子类初始化都会经过这条路。先上代码。
    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          // 1.Prepare this context for refreshing.
          prepareRefresh();
    
          // 2.Tell the subclass to refresh the internal bean factory.
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
          // 3.Prepare the bean factory for use in this context.
          prepareBeanFactory(beanFactory);
    
          try {
             //4. Allows post-processing of the bean factory in context subclasses.
             postProcessBeanFactory(beanFactory);
    
             // 5.Invoke factory processors registered as beans in the context.
             invokeBeanFactoryPostProcessors(beanFactory);
    
             // 6.Register bean processors that intercept bean creation.
             registerBeanPostProcessors(beanFactory);
    
             // 7.Initialize message source for this context.
             initMessageSource();
    
             // 8.Initialize event multicaster for this context.
             initApplicationEventMulticaster();
    
             // 9.Initialize other special beans in specific context subclasses.
             onRefresh();
    
             // 10.Check for listener beans and register them.
             registerListeners();
    
             // 11.Instantiate all remaining (non-lazy-init) singletons.
             finishBeanFactoryInitialization(beanFactory);
    
             // 12.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...
             //13.
          resetCommonCaches();
          }
       }
    }
     
    一共13步,这个过程比较难产和漫长,但结果是喜出望外的。分别来看下 每一步都干了什么。
    注意这个方法是加锁的。
      // 1.Prepare this context for refreshing.
    prepareRefresh();
    顾名思义,是准备工作,这个和前面初始化的准备工作不同。这个是进行参数配置的。placeholder解析和校验工作,但是主要针对web项目的。暂时先不看。

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

     // 3.Prepare the bean factory for use in this context.
    prepareBeanFactory(beanFactory);
    上代码:
    /**
     * Configure the factory's standard context characteristics,
     * such as the context's ClassLoader and post-processors.
     * @param beanFactory the BeanFactory to configure
     */
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       // Tell the internal bean factory to use the context's class loader etc.
      首先,设置了类加载器
       beanFactory.setBeanClassLoader(getClassLoader());
    
      添加对spel的支持,
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
      添加一个默认的properties的处理工具
       beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
       // Configure the bean factory with context callbacks.
      //设置需要忽略的类,这些类实现了如下的接口需要在bean创建的阶段在beanFactory的容器级别对自动装配进行忽略,而交由context容器进行callback注入。
       beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
       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.
      设置扩展点,对于这些扩展点接口的实现bean需要走特殊的callback流程,特殊装备规则。
       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.
    注册特殊的基础bean 如 environment systemEnvironment,systemProperties
    
       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. Allows post-processing of the bean factory in context subclasses.  给web项目使用,通常不会与自定义产生交集。
    postProcessBeanFactory(beanFactory);
     
    /* 5 .. 扩展点开始,调用BeanFactoryPostProcessors接口的 postProcessBeanFactory 方法。这里有些细节,会有处理的优先级。
    首先处理 BeanDefinitionRegistryPostProcessor 中带有PriorityOrdered ,Ordered 这些接口的实现,
    然后处理 实现了BeanDefinitionRegistryPostProcessor接口不带order的类。
    再然后处理 实现了 BeanFactoryPostProcessor 中带有PriorityOrdered ,Ordered 这些接口的实现。
    最后处理 实现了 BeanFactoryPostProcessor 但没有order 接口的实现类。


    这里也会进入 beanFactory获取Bean的关键方法
    doGetBean();方法位于AbstractBeanFactory中。
    getbean的实现比较简单,检查依赖 getDependsOn ,检查是否有循环依赖,有依赖的话先load依赖,AbstractAutowireCapableFactory 的 createBean();方法进行bean的创建。
    最后是在SimpleInstantiationStrategy 调用 Beanutils.instantiateClass()通过调用无参构造函数newinstance();创建得到bean实例。如果是单例会被缓存一份。

    在创建bean的同时,调用aware接口。通常只会用BeanNameAware 接口来更改名字。
    private void invokeAwareMethods(final String beanName, final Object bean) {
       if (bean instanceof Aware) {
          if (bean instanceof BeanNameAware) {
             ((BeanNameAware) bean).setBeanName(beanName);
          }
          if (bean instanceof BeanClassLoaderAware) {
             ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
          }
          if (bean instanceof BeanFactoryAware) {
             ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
          }
       }
    }
    private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
            if (alreadySeen != null && alreadySeen.contains(beanName)) {
                return false;
            }
            String canonicalName = canonicalName(beanName);
            Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
            if (dependentBeans == null) {
                return false;
            }
            if (dependentBeans.contains(dependentBeanName)) {
                return true;
            }
            for (String transitiveDependency : dependentBeans) {
                if (alreadySeen == null) {
                    alreadySeen = new HashSet<String>();
                }
                alreadySeen.add(beanName);
                if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
                    return true;
                }
            }
            return false;
        }
    View Code
    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
            if (logger.isDebugEnabled()) {
                logger.debug("Creating instance of bean '" + beanName + "'");
            }
            RootBeanDefinition mbdToUse = mbd;
    
            // Make sure bean class is actually resolved at this point, and
            // clone the bean definition in case of a dynamically resolved Class
            // which cannot be stored in the shared merged bean definition.
            Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
            if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
                mbdToUse = new RootBeanDefinition(mbd);
                mbdToUse.setBeanClass(resolvedClass);
            }
    
            // Prepare method overrides.
            try {
                mbdToUse.prepareMethodOverrides();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                        beanName, "Validation of method overrides failed", ex);
            }
    
            try {
                // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
                Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
                if (bean != null) {
                    return bean;
                }
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                        "BeanPostProcessor before instantiation of bean failed", ex);
            }
    
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
    View Code
    public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
            Assert.notNull(ctor, "Constructor must not be null");
            try {
                ReflectionUtils.makeAccessible(ctor);
                return ctor.newInstance(args);
            }
            catch (InstantiationException ex) {
                throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
            }
            catch (IllegalAccessException ex) {
                throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
            }
            catch (IllegalArgumentException ex) {
                throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
            }
            catch (InvocationTargetException ex) {
                throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
            }
        }
    View Code
    
    
    再然后调用BeanPostProcessor的 postProcessBeforeInitialization方法。

    然后调用 InitializingBean接口的 afterPropertiesSet();此时bean已经被初始化,可对属性进行更改。

    再然后调用 BeanPostProcessor接口的 postProcessAfterInitialization 此时可以对bean进行进一步的修饰。

    最后将 单例缓存起来

    然后 BeanFactoryPostProcessor 调用 postProcessBeanFactory方法
    */
      
     // 5.Invoke factory processors registered as beans in the context.
    invokeBeanFactoryPostProcessors(beanFactory);  
    代码如下:
    public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<String>();
    
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    }
                    else {
                        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<BeanDefinitionRegistryPostProcessor>();
    
                // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
                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);
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
    
                // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
                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);
                currentRegistryProcessors.clear();
    
                // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
                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.
                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!
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            List<String> orderedPostProcessorNames = new ArrayList<String>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
            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<BeanFactoryPostProcessor>();
            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<BeanFactoryPostProcessor>();
            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();
        }
    View Code
    protected <T> T doGetBean(
                final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
                throws BeansException {
    
            final String beanName = transformedBeanName(name);
            Object bean;
    
            // Eagerly check singleton cache for manually registered singletons.
            Object sharedInstance = getSingleton(beanName);
            if (sharedInstance != null && args == null) {
                if (logger.isDebugEnabled()) {
                    if (isSingletonCurrentlyInCreation(beanName)) {
                        logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                                "' that is not fully initialized yet - a consequence of a circular reference");
                    }
                    else {
                        logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                    }
                }
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
            }
    
            else {
                // Fail if we're already creating this bean instance:
                // We're assumably within a circular reference.
                if (isPrototypeCurrentlyInCreation(beanName)) {
                    throw new BeanCurrentlyInCreationException(beanName);
                }
    
                // Check if bean definition exists in this factory.
                BeanFactory parentBeanFactory = getParentBeanFactory();
                if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                    // Not found -> check parent.
                    String nameToLookup = originalBeanName(name);
                    if (args != null) {
                        // Delegation to parent with explicit args.
                        return (T) parentBeanFactory.getBean(nameToLookup, args);
                    }
                    else {
                        // No args -> delegate to standard getBean method.
                        return parentBeanFactory.getBean(nameToLookup, requiredType);
                    }
                }
    
                if (!typeCheckOnly) {
                    markBeanAsCreated(beanName);
                }
    
                try {
                    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                    checkMergedBeanDefinition(mbd, beanName, args);
    
                    // Guarantee initialization of beans that the current bean depends on.
                    String[] dependsOn = mbd.getDependsOn();
                    if (dependsOn != null) {
                        for (String dep : dependsOn) {
                            if (isDependent(beanName, dep)) {
                                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                            }
                            registerDependentBean(dep, beanName);
                            getBean(dep);
                        }
                    }
    
                    // Create bean instance.
                    if (mbd.isSingleton()) {
                        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                            @Override
                            public Object getObject() throws BeansException {
                                try {
                                    return createBean(beanName, mbd, args);
                                }
                                catch (BeansException ex) {
                                    // Explicitly remove instance from singleton cache: It might have been put there
                                    // eagerly by the creation process, to allow for circular reference resolution.
                                    // Also remove any beans that received a temporary reference to the bean.
                                    destroySingleton(beanName);
                                    throw ex;
                                }
                            }
                        });
                        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                    }
    
                    else if (mbd.isPrototype()) {
                        // It's a prototype -> create a new instance.
                        Object prototypeInstance = null;
                        try {
                            beforePrototypeCreation(beanName);
                            prototypeInstance = createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                    }
    
                    else {
                        String scopeName = mbd.getScope();
                        final Scope scope = this.scopes.get(scopeName);
                        if (scope == null) {
                            throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                        }
                        try {
                            Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                                @Override
                                public Object getObject() throws BeansException {
                                    beforePrototypeCreation(beanName);
                                    try {
                                        return createBean(beanName, mbd, args);
                                    }
                                    finally {
                                        afterPrototypeCreation(beanName);
                                    }
                                }
                            });
                            bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                        }
                        catch (IllegalStateException ex) {
                            throw new BeanCreationException(beanName,
                                    "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                    ex);
                        }
                    }
                }
                catch (BeansException ex) {
                    cleanupAfterBeanCreationFailure(beanName);
                    throw ex;
                }
            }
    
            // Check if required type matches the type of the actual bean instance.
            if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
                try {
                    return getTypeConverter().convertIfNecessary(bean, requiredType);
                }
                catch (TypeMismatchException ex) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Failed to convert bean '" + name + "' to required type '" +
                                ClassUtils.getQualifiedName(requiredType) + "'", ex);
                    }
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
            }
            return (T) bean;
        }
    View Code
    
    
     // 6.Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);
    第6步和第5步相似,也是根据 带有PriorityOrdered ,Ordered 这些接口的实现的实现判断优先级,这一步仅仅是注册BeanPostProcessor。并不做处理。
    
    
     // 7.Initialize message source for this context. 注册messagesource
    initMessageSource();


    //8.注册一个SimpleApplicationEventMulticaster到beanFactory中,同时abstractapplicationcontext也持有这个类。 作为spring事件发布机制。这个后面专门讲spring的事件机制。
    this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
    beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
     // 8.Initialize event multicaster for this context.
    initApplicationEventMulticaster();



    //9. 这也是为web服务使用的,主要是加载主体 initThemeSource
    // 9.Initialize other special beans in specific context subclasses.
    onRefresh();


    //10. 从bean工厂中 找到ApplicationListener.class 的实现类,并加入到第8步中的SimpleApplicationEventMulticaster 中。
    // 10.Check for listener beans and register them.
    registerListeners();

    // 11.Instantiate all remaining (non-lazy-init) singletons. 主要工作注册placeholder,初始化不需要懒加载的bean。
    finishBeanFactoryInitialization(beanFactory);

    // 12.Last step: publish corresponding event. 发布各种event事件。
    finishRefresh();


    //13.  清理工作 。清理metadata 缓存,classloader缓存。
    resetCommonCaches();


    至此,spring 启动完毕。

    下期开始看spring中的事件处理,后期梳理spring用到的设计模式。




  • 相关阅读:
    cmanformat
    mysql-sql语言参考
    jQuery 判断多个 input checkbox 中至少有一个勾选
    Java实现 蓝桥杯 算法提高 计算行列式
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 算法提高 成绩排序2
    Java实现 蓝桥杯 算法提高 成绩排序2
    Java实现 蓝桥杯 算法提高 成绩排序2
  • 原文地址:https://www.cnblogs.com/luoluoshidafu/p/8933574.html
Copyright © 2011-2022 走看看