zoukankan      html  css  js  c++  java
  • [心得体会]Spring容器的初始化

    1. Spring容器的初始化过程

    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {   
       this();  
       register(annotatedClasses);  
       refresh();
    }

    1. this() 方法的执行过程

    (1) 父类构造方法的初始化

    1) 在DefaultResourceLoader 类里面初始化创建了个classLoad2) PathMatchingResourcePatternResolver

    ① 初始化了resourceLoader 属性

    ② 同时创建了

    private PathMatcher pathMatcher = new AntPathMatcher(); 

    3) GenericApplicationContext类初始化this.beanFactory

        public GenericApplicationContext() {
    this.beanFactory = new DefaultListableBeanFactory();
    }

    跟进DefaultListableBeanFactory这个方法

    public DefaultListableBeanFactory() {   super();}
    public AbstractAutowireCapableBeanFactory() {
    super();
    ignoreDependencyInterface(BeanNameAware.class);
    ignoreDependencyInterface(BeanFactoryAware.class);
    ignoreDependencyInterface(BeanClassLoaderAware.class);
    }

    上面这个代码主要的功能就是初始化很多属性, 比如Map之类的属性并且忽略了三个Aware

    (2) 方法AnnotatedBeanDefinitionReader(this)的执行

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    this(registry, getOrCreateEnvironment(registry));
    }
    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);
    }

    public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
    registerAnnotationConfigProcessors(registry, null);
    }

    进入上面的方法之后一顿操作就做了两件事情

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

    初始化了两个对象

    DependencyComparator

    AutowireCandidateResolver

    注册了几个处理器

    org.springframework.context.annotation.internalConfigurationAnnotationProcessor

    org.springframework.context.annotation.internalAutowiredAnnotationProcessor

    org.springframework.context.annotation.internalCommonAnnotationProcessor

    org.springframework.context.annotation.internalPersistenceAnnotationProcessor

    org.springframework.context.event.internalEventListenerProcessor

    org.springframework.context.event.internalEventListenerFactory

    (3) 方法ClassPathBeanDefinitionScanner(this)的执行

        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) {

    this(registry, useDefaultFilters, environment,
    (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
    }

        public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
    Environment environment, @Nullable 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.trace("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.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
    }
    catch (ClassNotFoundException ex) {
    // JSR-330 API not available - simply skip.
    }
    }

    2. 配置类的扫描和注册

    (1) register(annotatedClasses)注册方式

    private final AnnotatedBeanDefinitionReader reader; // bean读取加载器
        public void register(Class<?>... annotatedClasses) {
    Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
    this.reader.register(annotatedClasses);
    }

    <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
    @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

       // 作用: 将Class类保存到abd对象里面, 并且保存了这个配置类中的所以注解
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
      // 判断是否存在condition注解, 是否可以跳过
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
    return;
    }

    abd.setInstanceSupplier(instanceSupplier);
      // 解析scope注解
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
      // 设置这个注解的value
    abd.setScope(scopeMetadata.getScopeName());
      // 获取beanName名字
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    // 判断是否有: lazy Primary dependsOn role description 这些注解
    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));
    }
    }
    }
    for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
    customizer.customize(abd);
    }
    // 创建BeanDefinitionHolder
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
      // 创建代理类
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
      // 注册beandefinition
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }

    (2) 使用scan(basePackages)实现的注册

    public int scan(String... basePackages) {
       int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
    // 扫描包
       doScan(basePackages);

       // 这里就是this()方法里面执行的注册的6个类, 不过现在默认不会再初始化了
       if (this.includeAnnotationConfig) {
           AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
      }

       return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
    }

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
       Assert.notEmpty(basePackages, "At least one base package must be specified");
       Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
       // 这个就是我们 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("com"); 定义的扫描包的位置, 里面基本上都是配置类
       for (String basePackage : basePackages) {
           // 扫描出所有我们定义的bean
           Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
           for (BeanDefinition candidate : candidates) {
               // scope 的读取和设置
               ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
               candidate.setScope(scopeMetadata.getScopeName());
               // 生成BeanName的名字
               String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
               if (candidate instanceof AbstractBeanDefinition) {
                   // 初始化后置处理器
                   postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
              }
               if (candidate instanceof AnnotatedBeanDefinition) {
                   // 判断是否有 lazy dependsOn role description 属性
                   AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
              }
               if (checkCandidate(beanName, candidate)) {
                   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                   definitionHolder =
                           AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                   // 把BeanDefinition设置到备份的这个对象中, 到时候返回
                   beanDefinitions.add(definitionHolder);
                   // 注册BeanDefinition
                   registerBeanDefinition(definitionHolder, this.registry);
              }
          }
      }
       return beanDefinitions;
    }

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

    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;
    }

    @Override
    public Resource[] getResources(String locationPattern) throws IOException {
       Assert.notNull(locationPattern, "Location pattern must not be null");
       if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
           // a class path resource (multiple resources for same name possible)
           if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
               // a class path resource pattern
               return findPathMatchingResources(locationPattern);
          }
           else {
               // all class path resources with the given name
               return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
          }
      }
       else {
           // Generally only look for a pattern after a prefix here,
           // and on Tomcat only after the "*/" separator for its "war:" protocol.
           int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
                   locationPattern.indexOf(':') + 1);
           if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
               // a file pattern
               return findPathMatchingResources(locationPattern);
          }
           else {
               // a single resource with the given name
               return new Resource[] {getResourceLoader().getResource(locationPattern)};
          }
      }
    }

    protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
       String rootDirPath = determineRootDir(locationPattern);
       String subPattern = locationPattern.substring(rootDirPath.length());
       // 获取包目录
       Resource[] rootDirResources = getResources(rootDirPath);
       Set<Resource> result = new LinkedHashSet<>(16);
       // 遍历包, com.zhazha.dao, com.zhazha.service, com.zhazha.controller
       for (Resource rootDirResource : rootDirResources) {
           rootDirResource = resolveRootDirResource(rootDirResource);
           URL rootDirUrl = rootDirResource.getURL();
           if (equinoxResolveMethod != null && rootDirUrl.getProtocol().startsWith("bundle")) {
               URL resolvedUrl = (URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, rootDirUrl);
               if (resolvedUrl != null) {
                   rootDirUrl = resolvedUrl;
              }
               rootDirResource = new UrlResource(rootDirUrl);
          }
           if (rootDirUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
               result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirUrl, subPattern, getPathMatcher()));
          }
           else if (ResourceUtils.isJarURL(rootDirUrl) || isJarResource(rootDirResource)) {
               result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirUrl, subPattern));
          }
           else {
               // 遍历出一个包, 放入这个方法进行扫描字节码文件
               result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
          }
      }
       if (logger.isTraceEnabled()) {
           logger.trace("Resolved location pattern [" + locationPattern + "] to resources " + result);
      }
       return result.toArray(new Resource[0]);
    }

    protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern)
    throws IOException {

       File rootDir;
       try {
           rootDir = rootDirResource.getFile().getAbsoluteFile();
      }
       catch (FileNotFoundException ex) {
           if (logger.isDebugEnabled()) {
               logger.debug("Cannot search for matching files underneath " + rootDirResource +
                       " in the file system: " + ex.getMessage());
          }
           return Collections.emptySet();
      }
       catch (Exception ex) {
           if (logger.isInfoEnabled()) {
               logger.info("Failed to resolve " + rootDirResource + " in the file system: " + ex);
          }
           return Collections.emptySet();
      }
       // 遍历com.zhazha.dao这个包里面的.class字节码文件
       return doFindMatchingFileSystemResources(rootDir, subPattern);
    }

    protected Set<Resource> doFindMatchingFileSystemResources(File rootDir, String subPattern) throws IOException {
       if (logger.isTraceEnabled()) {
           logger.trace("Looking for matching resources in directory tree [" + rootDir.getPath() + "]");
      }
       // 获得.class字节码文件的列表
       Set<File> matchingFiles = retrieveMatchingFiles(rootDir, subPattern);
       Set<Resource> result = new LinkedHashSet<>(matchingFiles.size());
       // 把发现的所有.class文件的file对象放入result中, 这个result是资源的
       for (File file : matchingFiles) {
           result.add(new FileSystemResource(file));
      }
       return result;
    }

    protected Set<File> retrieveMatchingFiles(File rootDir, String pattern) throws IOException {
       if (!rootDir.exists()) {
           // Silently skip non-existing directories.
           if (logger.isDebugEnabled()) {
               logger.debug("Skipping [" + rootDir.getAbsolutePath() + "] because it does not exist");
          }
           return Collections.emptySet();
      }
       if (!rootDir.isDirectory()) {
           // Complain louder if it exists but is no directory.
           if (logger.isInfoEnabled()) {
               logger.info("Skipping [" + rootDir.getAbsolutePath() + "] because it does not denote a directory");
          }
           return Collections.emptySet();
      }
       if (!rootDir.canRead()) {
           if (logger.isInfoEnabled()) {
               logger.info("Skipping search for matching files underneath directory [" + rootDir.getAbsolutePath() +
                       "] because the application is not allowed to read the directory");
          }
           return Collections.emptySet();
      }
       String fullPattern = StringUtils.replace(rootDir.getAbsolutePath(), File.separator, "/");
       if (!pattern.startsWith("/")) {
           fullPattern += "/";
      }
       fullPattern = fullPattern + StringUtils.replace(pattern, File.separator, "/");
       Set<File> result = new LinkedHashSet<>(8);
       // 匹配字节码文件.class, 将结果放入result
       doRetrieveMatchingFiles(fullPattern, rootDir, result);
       return result;
    }

    protected void doRetrieveMatchingFiles(String fullPattern, File dir, Set<File> result) throws IOException {
       if (logger.isTraceEnabled()) {
           logger.trace("Searching directory [" + dir.getAbsolutePath() +
                   "] for files matching pattern [" + fullPattern + "]");
      }
       // 获取包下面的所有文件, 不断的遍历直到找到.class
       for (File content : listDirectory(dir)) {
           String currPath = StringUtils.replace(content.getAbsolutePath(), File.separator, "/");
           if (content.isDirectory() && getPathMatcher().matchStart(fullPattern, currPath + "/")) {
               // 不可读的话
               if (!content.canRead()) {
                   if (logger.isDebugEnabled()) {
                       logger.debug("Skipping subdirectory [" + dir.getAbsolutePath() +
                               "] because the application is not allowed to read the directory");
                  }
              }
               else {
                   // 回调方法
                   doRetrieveMatchingFiles(fullPattern, content, result);
              }
          }
           // 把找到的.class字节码放入结果中
           if (getPathMatcher().match(fullPattern, currPath)) {
               result.add(content);
          }
      }
    }

    3. refresh方法详情

    总共分为13个步骤

    @Override
    	public void refresh() throws BeansException, IllegalStateException {
    		synchronized (this.startupShutdownMonitor) {
    			// 准备此上下文以进行刷新。
    			prepareRefresh();
    
    			// 告诉子类刷新内部bean工厂。
    			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
    			// 准备在这种情况下使用的bean工厂。
    			prepareBeanFactory(beanFactory);
    
    			try {
    				// 允许在上下文子类中对bean工厂进行后处理。(但是里面的方法是空的)
    				postProcessBeanFactory(beanFactory);
    
    				// 调用在上下文中注册为bean的工厂处理器。
    				invokeBeanFactoryPostProcessors(beanFactory);
    
    				// 注册拦截Bean创建的Bean处理器。
    				registerBeanPostProcessors(beanFactory);
    
    				// 为此上下文初始化消息源。
    				initMessageSource();
    
    				// 为此上下文初始化事件多播器。
    				initApplicationEventMulticaster();
    
    				// 在特定上下文子类中初始化其他特殊bean。
    				onRefresh();
    
    				// 检查侦听器bean并注册它们。
    				registerListeners();
    
    				// 实例化所有剩余的(非延迟初始化)单例。
    				finishBeanFactoryInitialization(beanFactory);
    
    				// 最后一步:发布相应的事件。
    				finishRefresh();
    			}
    
    			catch (BeansException ex) {
    				if (logger.isWarnEnabled()) {
    					logger.warn("Exception encountered during context initialization - " +
    							"cancelling refresh attempt: " + ex);
    				}
    
    				// 销毁已创建的单例以避免资源悬空。
    				destroyBeans();
    
    				// 重置“活动”标志。
    				cancelRefresh(ex);
    
    				// 将异常传播给呼叫者。
    				throw ex;
    			}
    
    			finally {
    				// 在Spring的核心中重置常见的自省缓存,因为我们可能再也不需要单例bean的元数据了。
    				resetCommonCaches();
    			}
    		}
    	}
    

    (1) 准备此上下文以进行刷新

    protected void prepareRefresh() {
    		// 获取spring容器开启时间
    		this.startupDate = System.currentTimeMillis();
        	// 标记closed属性为false
    		this.closed.set(false);
    		// 激活标志为true
    		this.active.set(true);
    
    		if (logger.isDebugEnabled()) {
    			if (logger.isTraceEnabled()) {
    				logger.trace("Refreshing " + this);
    			}
    			else {
    				logger.debug("Refreshing " + getDisplayName());
    			}
    		}
    
    		// 在上下文环境中初始化任何占位符属性源
    		initPropertySources();
    
    		// 验证所有标记为必需的属性都是可解析的:
    		// see ConfigurablePropertyResolver#setRequiredProperties
    		getEnvironment().validateRequiredProperties();
    
    		// 存储预刷新应用程序 / 监听器..。
    		if (this.earlyApplicationListeners == null) {
    			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    		}
    		else {
    			// 将本地应用程序侦听器重置为预刷新状态。
    			this.applicationListeners.clear();
    			this.applicationListeners.addAll(this.earlyApplicationListeners);
    		}
    
    		// 允许收集早期应用程序事件,以便在多管道可用时发布..。
    		this.earlyApplicationEvents = new LinkedHashSet<>();
    	}
    

    添加监听器

    (2) 告诉子类刷新内部bean工厂

    	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
            // 产生id
    		refreshBeanFactory();
    		return getBeanFactory();
    	}
    
    里面就这一句话
    this.beanFactory.setSerializationId(getId());
    

    (3) 准备在这种情况下使用的bean工厂

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 告诉内部 bean 工厂使用上下文的类装入器等
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
        // 使用上下文回调配置 bean 工厂
        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 接口未注册为可解析类型。
        // Messagesource 以 bean 的形式注册(并在自动装配中找到)。
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
        // 将检测内部 bean 的早期后处理程序注册为 ApplicationListeners。
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
        // 检测 LoadTimeWeaver 并准备编织(如果发现)。
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // 设置用于类型匹配的临时 ClassLoader。
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    
        // 注册默认环境 bean。
        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) 允许在上下文子类中对bean工厂进行后处理。(但是里面的方法是空的)

    内部方法为空

    (5) 调用在上下文中注册为bean的工厂后置处理器

    invokeBeanFactoryPostProcessors(beanFactory);
    
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 传入beanFactory和所有的PostProcessors, 进行PostProcessors的注册
        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()));
        }
    }
    

    把注解放入List<BeanDefinitionHolder> configCandidates = new ArrayList<>();

    // 配置类的解析读取器: 解析ComponeScan注解扫描的所有bean
    ConfigurationClassParser parser = new ConfigurationClassParser(
    				this.metadataReaderFactory, this.problemReporter, this.environment,
    				this.resourceLoader, this.componentScanBeanNameGenerator, registry);
    
    // 这里开始真正的解析
    parser.parse(candidates);
    

    最终解析完毕之后会把对象放入parser的configurationClasses属性之中

    public void parse(Set<BeanDefinitionHolder> configCandidates) {
        for (BeanDefinitionHolder holder : configCandidates) {
            BeanDefinition bd = holder.getBeanDefinition();
            try {
                if (bd instanceof AnnotatedBeanDefinition) {
                    // 我们的这个案例最终往这里走
                    parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
                }
                else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
                    parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
                }
                else {
                    parse(bd.getBeanClassName(), holder.getBeanName());
                }
            }
            catch (BeanDefinitionStoreException ex) {
                throw ex;
            }
            catch (Throwable ex) {
                throw new BeanDefinitionStoreException(
                        "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
            }
        }
    
        this.deferredImportSelectorHandler.process();
    }
    
    protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
        // 检测条件判断
        if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
            return;
        }
    	// 判断容器是否已经存在这个配置类
        ConfigurationClass existingClass = this.configurationClasses.get(configClass);
        if (existingClass != null) {
            if (configClass.isImported()) {
                if (existingClass.isImported()) {
                    // 合并
                    existingClass.mergeImportedBy(configClass);
                }
                // Otherwise ignore new imported config class; existing non-imported class overrides it.
                return;
            }
            else {
                // Explicit bean definition found, probably replacing an import.
                // Let's remove the old one and go with the new one.
                this.configurationClasses.remove(configClass);
                this.knownSuperclasses.values().removeIf(configClass::equals);
            }
        }
    
        // 递归地处理配置类及其超类层次结构.
        SourceClass sourceClass = asSourceClass(configClass);
        do {
            sourceClass = doProcessConfigurationClass(configClass, sourceClass);
        }
        while (sourceClass != null);
    
        this.configurationClasses.put(configClass, configClass);
    }
    
    // 处理任何@componentscan 注释
    Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
        sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
    if (!componentScans.isEmpty() &&
        !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
        for (AnnotationAttributes componentScan : componentScans) {
            // 配置类使用@componentscan 注释——立即执行扫描
            Set<BeanDefinitionHolder> scannedBeanDefinitions =
                    this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
            // 检查任何进一步配置类的扫描定义集,并在需要时递归地解析
            for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                if (bdCand == null) {
                    bdCand = holder.getBeanDefinition();
                }
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                    parse(bdCand.getBeanClassName(), holder.getBeanName());
                }
            }
        }
    }
    
    public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
        // 类扫描工具
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
                componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
    
        Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
        boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
        scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
                BeanUtils.instantiateClass(generatorClass));
    
        ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
        if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
            scanner.setScopedProxyMode(scopedProxyMode);
        }
        else {
            Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
            scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
        }
    	// 获取扫描包路径的.class字节码文件
        scanner.setResourcePattern(componentScan.getString("resourcePattern"));
    	// 添加包括类型过滤器
        for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
            for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                scanner.addIncludeFilter(typeFilter);
            }
        }
        // 添加排除类型过滤器
        for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
            for (TypeFilter typeFilter : typeFiltersFor(filter)) {
                scanner.addExcludeFilter(typeFilter);
            }
        }
    	// 设置懒加载状态
        boolean lazyInit = componentScan.getBoolean("lazyInit");
        if (lazyInit) {
            scanner.getBeanDefinitionDefaults().setLazyInit(true);
        }
    	// 把包componentScan扫描获取的Bean全部放入这个对象中
        Set<String> basePackages = new LinkedHashSet<>();
        // 获取componentScan扫描包路径的表达式
        String[] basePackagesArray = componentScan.getStringArray("basePackages");
        for (String pkg : basePackagesArray) {
            String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
                    ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
            Collections.addAll(basePackages, tokenized);
        }
        for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
            basePackages.add(ClassUtils.getPackageName(clazz));
        }
        
        if (basePackages.isEmpty()) {
            // 获取本类位置的package包的路径
            basePackages.add(ClassUtils.getPackageName(declaringClass));
        }
    	// 排除掉本类的路径, 防止重复注册
        scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
            @Override
            protected boolean matchClassName(String className) {
                return declaringClass.equals(className);
            }
        });
        // 做扫描, 返回注解扫描出来的所有类, 并且注册扫描出来的组件到容器中
        return scanner.doScan(StringUtils.toStringArray(basePackages));
    }
    

    private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
        Set<BeanDefinition> candidates = new LinkedHashSet<>();
        try {
            // 组装 com.**.class
            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    resolveBasePackage(basePackage) + '/' + this.resourcePattern;
            // 获取所有子类的class字节码
            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;
    }
    

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Assert.notEmpty(basePackages, "At least one base package must be specified");
        // 将我们需要扫描到的类加入到这里, 比如UserDao这种
        Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
        // 遍历前面获取的所有.class字节码文件的路径
        for (String basePackage : basePackages) {
            // 判断是否是我们需要的组件, 比如UserDao UserService UserController 这种, 不包括配置类
            Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
            for (BeanDefinition candidate : candidates) {
                // 获取scope, 并且设置scope
                ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                candidate.setScope(scopeMetadata.getScopeName());
                // 获取bean的名字, 这里的名字不包含包名
                String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                // 设置默认Beandefinition的默认属性, 例如lazy InitMethodName AutowireMode DestroyMethodName 这类属性
                if (candidate instanceof AbstractBeanDefinition) {
                    postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                }
                if (candidate instanceof AnnotatedBeanDefinition) {
                    // 设置lazy Primary dependsOn role description
                    AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                }
                if (checkCandidate(beanName, candidate)) {
                    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                    definitionHolder =
                            AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                    beanDefinitions.add(definitionHolder);
                    // 注册UserDao这样的组件
                    registerBeanDefinition(definitionHolder, this.registry);
                }
            }
        }
        return beanDefinitions;
    }
    

    (6) 注册拦截Bean创建的Bean处理器

    注册bean的后置处理器

    registerBeanPostProcessors(beanFactory)
    
    org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
    
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 这个beanFactory就是DefaultListableBeanFactory, 这个this就是AnnotationConfigApplicationContext
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }
    

    注册PostProcessors

    // 根据类型获取容器中的postProcessor
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    

    根据不同PostProcessor继承的接口把不同的PostProcess放入不同的集合

    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    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);
        }
    }
    
    // 注册继承了priority的PostProcessor
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
    // 注册实现了Ordered的PostProcessor
    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);
    
    // 注册所有常规的PostProcessor
    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);
    
    // 注册内部类
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);
    
    // 将检测内部 bean 的后处理器重新注册为 ApplicationListeners,将其移动到处理器链的末尾(用于接收代理等)。
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    

    (7) 为此上下文初始化消息源

    initMessageSource();
    

    内部做了个消息源的单例的注册

    (8) 为此上下文初始化事件多播器

    this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
    			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    

    (9) 在特定上下文子类中初始化其他特殊bean

    	protected void onRefresh() throws BeansException {
    		// For subclasses: do nothing by default.
    	}
    

    (10) 检查侦听器bean并注册它们

    registerListeners();
    
    protected void registerListeners() {
        // 先注册静态指定的侦听器。
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }
    
        // 不要在这里初始化 FactoryBeans: 我们需要保留所有未初始化的常规 beans,以便将后处理器应用于它们!
        // 这里其实就是拿到application中的监听器
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }
    
        // 发布早期的应用程序事件,现在我们终于有了一个多主机..
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }
    

    (11) 实例化所有剩余的(非延迟初始化)单例

    finishBeanFactoryInitialization(beanFactory);
    
    beanFactory.preInstantiateSingletons(); // 里面最重要的方法
    
    public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("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.
        // 里面存入beandefinition的名字
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
        // Trigger initialization of all non-lazy singleton beans...
        // 遍历这个definitionBean的名字
        for (String beanName : beanNames) {
            // 获取BeanDefinition
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 是工厂类么?
                if (isFactoryBean(beanName)) {
                    // 根据完整的包名获取对象 FACTORY_BEAN_PREFIX = &
                    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 {
                    // 根据这个bean获取对象, 如果没有则创建这个bean
                    getBean(beanName);
                }
            }
        }
    
        // 触发所有适用bean的初始化后回调...
        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) 最后一步:发布相应的事件

    (13) 在Spring的核心中重置常见的自省缓存,因为我们可能再也不需要单例bean的元数据了






  • 相关阅读:
    Android开发使用Glide获取图片背景色淡绿色解决办法
    Android 获取 View 宽高的常用正确方式,避免为零
    Android之自定义View来接收输入法输入的内容
    FileProvider使用详解(拍照、安装APP、共享文件)
    简明 homebrew
    更优雅地使用命令行
    一篇长文说 git 基础
    chrome 浏览器的使用技巧
    前端学命令行
    cocos 碰撞系统
  • 原文地址:https://www.cnblogs.com/bangiao/p/12418308.html
Copyright © 2011-2022 走看看