死磕Spring之IoC篇 - BeanDefinition 的解析过程(面向注解) (3)

【核心】扫描包路径,通过 ASM(Java 字节码的操作和分析框架)解析出所有符合条件的 BeanDefinition,调用父类的 findCandidateComponents(String basePackage) 方法

对第 2 步解析出来的 BeanDefinition 依次处理,并注册

解析出 @Scope 注解的元信息并设置

获取或者生成一个的名称 beanName

设置相关属性的默认值

根据这个类的相关注解设置属性值(存在则会覆盖默认值)

检查 beanName 是否已存在,已存在但是不兼容则会抛出异常

将 BeanDefinition 封装成 BeanDefinitionHolder 对象,这里多了一个 beanName

如果代理模式是 TARGET_CLASS,则再创建一个 BeanDefinition 代理对象(重新设置了相关属性),原始 BeanDefinition 已注册

添加至 beanDefinitions 集合

注册该 BeanDefinition

返回 beanDefinitions(已注册的 BeanDefinition 集合)

第 2 步是这个扫描过程的核心步骤,在父类 ClassPathScanningCandidateComponentProvider 中进行分析,接下来的处理过程不复杂,获取相关属性进行配置

第 7 步创建代理对象,和 AOP 相关,感兴趣的可自行查看

ClassPathScanningCandidateComponentProvider

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider,classpath 下扫描符合条件的 BeanDefinition

构造函数 public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware { static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; private String resourcePattern = DEFAULT_RESOURCE_PATTERN; /** 包含过滤器 */ private final List<TypeFilter> includeFilters = new LinkedList<>(); /** 排除过滤器 */ private final List<TypeFilter> excludeFilters = new LinkedList<>(); @Nullable private Environment environment; /** {@link Condition} 注解计算器 */ @Nullable private ConditionEvaluator conditionEvaluator; /** 资源加载器,默认 PathMatchingResourcePatternResolver */ @Nullable private ResourcePatternResolver resourcePatternResolver; /** MetadataReader 工厂 */ @Nullable private MetadataReaderFactory metadataReaderFactory; /** 所有 `META-INF/spring.components` 文件的内容 */ @Nullable private CandidateComponentsIndex componentsIndex; protected ClassPathScanningCandidateComponentProvider() { } public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters) { this(useDefaultFilters, new StandardEnvironment()); } public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) { if (useDefaultFilters) { registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(null); } @Override public void setResourceLoader(@Nullable ResourceLoader resourceLoader) { this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader); // 获取所有 `META-INF/spring.components` 文件中的内容 this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader()); } }

构造函数在上一小节的 ClassPathBeanDefinitionScanner 的构造函数中都已经讲过了

我们来看到 componentsIndex 属性,调用 CandidateComponentsIndexLoader#loadIndex(@Nullable ClassLoader classLoader) 方法生成的

CandidateComponentsIndexLoader

org.springframework.context.index.CandidateComponentsIndexLoader,CandidateComponentsIndexLoader 的加载器,代码如下:

public final class CandidateComponentsIndexLoader { public static final String COMPONENTS_RESOURCE_LOCATION = "META-INF/spring.components"; public static final String IGNORE_INDEX = "spring.index.ignore"; private static final boolean shouldIgnoreIndex = SpringProperties.getFlag(IGNORE_INDEX); private static final Log logger = LogFactory.getLog(CandidateComponentsIndexLoader.class); /** CandidateComponentsIndex 的缓存,与 ClassLoader 对应 */ private static final ConcurrentMap<ClassLoader, CandidateComponentsIndex> cache = new ConcurrentReferenceHashMap<>(); private CandidateComponentsIndexLoader() { } @Nullable public static CandidateComponentsIndex loadIndex(@Nullable ClassLoader classLoader) { ClassLoader classLoaderToUse = classLoader; if (classLoaderToUse == null) { classLoaderToUse = CandidateComponentsIndexLoader.class.getClassLoader(); } // 获取所有 `META-INF/spring.components` 文件中的内容 return cache.computeIfAbsent(classLoaderToUse, CandidateComponentsIndexLoader::doLoadIndex); } @Nullable private static CandidateComponentsIndex doLoadIndex(ClassLoader classLoader) { // 是否忽略 Index 的提升,通过配置 `spring.index.ignore` 变量,默认为 `false` if (shouldIgnoreIndex) { return null; } try { // 获取所有的 `META-INF/spring.components` 文件 Enumeration<URL> urls = classLoader.getResources(COMPONENTS_RESOURCE_LOCATION); if (!urls.hasMoreElements()) { return null; } // 加载所有 `META-INF/spring.components` 文件的内容 List<Properties> result = new ArrayList<>(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); result.add(properties); } if (logger.isDebugEnabled()) { logger.debug("Loaded " + result.size() + "] index(es)"); } // 总共配置多少个 component 组件 int totalCount = result.stream().mapToInt(Properties::size).sum(); // 如果配置了 component 组件,则封装成 CandidateComponentsIndex 对象并返回 return (totalCount > 0 ? new CandidateComponentsIndex(result) : null); } catch (IOException ex) { throw new IllegalStateException("Unable to load indexes from location [" + COMPONENTS_RESOURCE_LOCATION + "]", ex); } } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywzdd.html