• AnnotationConfigApplicationContext bean注册


    一、AnnotationConfigApplicationContext 初始化reader、scanner,设置扫描路径
    二、ClassPathBeanDefinitionScanner负责根据扫描路径执行doScan(packages)扫描资源,并通过includeFilters和excludeFilters过滤后返回目标beanDefintion
    三、ClassPathBeanDefinitionScanner调用registerBeanDefinition(definitionHolder, this.registry)将bean注册进注册器。

    • AnnotationConfigApplicationContext("com.jty.spring.annotation")
    public AnnotationConfigApplicationContext(String... basePackages) {
                    //调用无参构造方法
    		this();
                    //组件扫描
    		scan(basePackages);
    		refresh();
    	}
    
    # this()初始化reader、scanner
    public AnnotationConfigApplicationContext() {
    		this.reader = new AnnotatedBeanDefinitionReader(this);
                    //this(registry, true);使用默认includeFilters(AnnotationTypeFilter注解类型过滤器,且注解类型为Component)
                    //初始化metadataReaderFactory=CachingMetadataReaderFactory,该元数据阅读器工厂返回元数据阅读器为SimpleMetadataReader,
                    //后面用来从Resource中读取元数据信息,即类定义信息
    		this.scanner = new ClassPathBeanDefinitionScanner(this);
    	}
    
    • AnnotationConfigApplicationContext.scan(basePackages);#调用scanner.scan(basePackages);
    • ClassPathBeanDefinitionScanner.scan(basePackages)
    public int scan(String... basePackages) {
                    //统计未扫描前容器中BeanDefinition数目
    		int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
                    //执行扫描操作
    		doScan(basePackages);
    
    		// Register annotation config processors, if necessary.
    		if (this.includeAnnotationConfig) {
    			AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    		}
                   //返回本次扫描注册的bean数目
    		return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
    	}
    
    • ClassPathBeanDefinitionScanner.doScan(basePackages)
    	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
    		Assert.notEmpty(basePackages, "At least one base package must be specified");
                    //用来保存BeanDefinitionHolder,该类用来包装BeanDefinition,还包括beanName、aliases属性
    		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
    		for (String basePackage : basePackages) {
                            //组件扫描,返回候选bean定义
    			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;
    	}
    
    • ClassPathScanningCandidateComponentProvider.findCandidateComponents(basePackage)
    #ClassPathBeanDefinitionScanner继承ClassPathScanningCandidateComponentProvider
    #ClassPathScanningCandidateComponentProvider通过类路径扫描或CandidateComponentsIndex查找候选者组件,
    #通过includeFilters包含过滤器和excludeFilters排除过滤器选则出目标候选者
    #如AnnotationTypeFilter用来过滤注解,通过注解类型
    public Set<BeanDefinition> findCandidateComponents(String basePackage) {
    		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
    			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
    		}
    		else {
    			return scanCandidateComponents(basePackage);
    		}
    	}
    
    • ClassPathScanningCandidateComponentProvider.scanCandidateComponents(basePackage)
    private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
    		Set<BeanDefinition> candidates = new LinkedHashSet<>();
    		try {
                            //解析扫描路径即扫描文件类型,如classpath*:com/jty/spring/annotation/**/*.class
    			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
    					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
                           //AbstractApplicationContext默认的创建PathMatchingResourcePatternResolver对象作为资源解析器
                           // 使用资源解析器解析PathMatchingResourcePatternResolver文件返回Resource类型对象。即将.class文件以Resource返回
    			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 {
                                                    //通过元数据阅读器从每个.class资源中读取元数据信息,即类定义的信息
    						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
    						if (isCandidateComponent(metadataReader)) {
                                                             /*
    	public ScannedGenericBeanDefinition(MetadataReader metadataReader) {
    		Assert.notNull(metadataReader, "MetadataReader must not be null");
                    //元信息
    		this.metadata = metadataReader.getAnnotationMetadata();
                    //类名
    		setBeanClassName(this.metadata.getClassName());
    	}
                                                              */
    							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;
    	}
    

    PathMatchingResourcePatternResolver.getResources(packageSearchPath)

    	public Resource[] getResources(String locationPattern) throws IOException {
    		Assert.notNull(locationPattern, "Location pattern must not be null");
                     //如果以classpath*:开头
    		if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
    			// a class path resource (multiple resources for same name possible)
                             //一个类路径资源(可能有多个名称相同的资源)
                             //classpath*:后路径包含‘*’、‘?’、‘{}’则执行这步。
                             //具体怎么获取,可查看PathMatchingResourcePatternResolver.findPathMatchingResources(String locationPattern) 
    			if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
    				// a class path resource pattern
                                    //返回匹配路径的所有资源
    				return findPathMatchingResources(locationPattern);
    			}
    			else {
                                    //否则执行,通过ClassLoader查找具有给定位置的所有类位置资源
    				// 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)};
    			}
    		}
    	}
    
    • ClassPathScanningCandidateComponentProvider.isCandidateComponent(sbd) #判断BeanDefinition是否时符合需求,即是否满足includeFilters包含过滤器和excludeFilters排除过滤器
    	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;
    	}
    
    • 返回ClassPathBeanDefinitionScanner.doScan(basePackages)
    	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
    		Assert.notEmpty(basePackages, "At least one base package must be specified");
                    //用来保存BeanDefinitionHolder,该类用来包装BeanDefinition,还包括beanName、aliases属性
    		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
    		for (String basePackage : basePackages) {
                            //组件扫描,返回候选bean定义,到这扫描步骤已经结束
    			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
    			for (BeanDefinition candidate : candidates) {
    				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                                    //设置作用域,BeanDefinition中默认为单例singleton
    				candidate.setScope(scopeMetadata.getScopeName());
                                    //默认使用类名简称shortClassName
    				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                                     //抽象类定义
    				if (candidate instanceof AbstractBeanDefinition) {
                                             //设置bean默认属性
    					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);
                                             //申请bean代理,若需要代理的话,将一个同该bean一样的代理bean注册
    					definitionHolder =
    							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    					beanDefinitions.add(definitionHolder);
                                            //注册该beanDefintion
    					registerBeanDefinition(definitionHolder, this.registry);
    				}
    			}
    		}
    		return beanDefinitions;
    	}
    
    • ClassPathBeanDefinitionScanner.postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName)
    protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
                    //bean默认设置具体可查看BeanDefinitionDefaults.java
    		beanDefinition.applyDefaults(this.beanDefinitionDefaults);
    		if (this.autowireCandidatePatterns != null) {
                            //连接到bean定义中自动注入的属性
    			beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
    		}
    	}
    
    • ClassPathBeanDefinitionScanner.registerBeanDefinition(definitionHolder, this.registry)
    protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
    		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
    	}
    
    • BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry)
    	public static void registerBeanDefinition(
    			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    			throws BeanDefinitionStoreException {
    
    		// Register bean definition under primary name.
    		String beanName = definitionHolder.getBeanName();
    		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    
    		// Register aliases for bean name, if any.
    		String[] aliases = definitionHolder.getAliases();
    		if (aliases != null) {
    			for (String alias : aliases) {
    				registry.registerAlias(beanName, alias);
    			}
    		}
    	}
    
    • GenericApplicationContext.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())
           //AnnotationConfigApplicationContext 继承GenericApplicationContext
    	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    			throws BeanDefinitionStoreException {
                    //DefaultListableBeanFactory 即为注册器又是beanFactory,将BeanDefinition添加到beanDefinitionMap,
                    //this.beanDefinitionMap.put(beanName, beanDefinition);
                    //bean注册结束
    		this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
    	}
    
  • 相关阅读:
    广陵基地输电线路实训场
    广陵基地配电网综合实训室
    广陵基地电缆实训室
    Windows Phone 9再见了!
    Windows Phone 8初学者开发—第23部分:测试并向应用商店提交
    Windows Phone 8初学者开发—第22部分:用演示图板创建卷盘的动画
    JDBC数据类型
    Java-BlockingQueue的使用
    苹果下如果安装nginx,给nginx安装markdown第三方插件
    苹果电脑包管理
  • 原文地址:https://www.cnblogs.com/jinit/p/13871889.html
Copyright © 2020-2023  润新知