BeanDefinition 解析流程
BeanDefinition 解析入口:ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
ConfigurationClassPostProcessor#
/**
* 从主配置类开始递归解析所有配置类,并注册相关的 BeanDefinition 到 BeanDefinitionRegistry 中
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 注册中心 ID
final int registryId = System.identityHashCode(registry);
if (registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
registriesPostProcessed.add(registryId);
// 处理配置类并注册 BeanDefinition
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
final List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 读取 BeanDefinitionRegistry 所有已注册的 bean
String[] candidateNames = registry.getBeanDefinitionNames();
for (final String beanName : candidateNames) {
final BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 1)尝试直接读取目标 BeanDefinition 的配置标识【已处理】
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// 2)尝试解析此 BeanDefinition 的配置标识写入
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 如果无 @Configuration 配置类,则直接返回
if (configCandidates.isEmpty()) {
return;
}
// 根据 @Order 注解的值对配置类进行排序
configCandidates.sort((bd1, bd2) -> {
final int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
final int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 尝试检测自定义的 BeanNameGenerator
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!localBeanNameGeneratorSet) {
final BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
componentScanBeanNameGenerator = generator;
importBeanNameGenerator = generator;
}
}
}
if (environment == null) {
environment = new StandardEnvironment();
}
// 创建 ConfigurationClassParser
final ConfigurationClassParser parser = new ConfigurationClassParser(
metadataReaderFactory, problemReporter, environment,
resourceLoader, componentScanBeanNameGenerator, registry);
final Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
final Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 解析目标配置类【第一个解析的是应用程序主类】
parser.parse(candidates);
parser.validate();
// 读取所有解析到的配置类
final Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// 创建 ConfigurationClassBeanDefinitionReader
if (reader == null) {
reader = new ConfigurationClassBeanDefinitionReader(
registry, sourceExtractor, resourceLoader, environment,
importBeanNameGenerator, parser.getImportRegistry());
}
// 解析配置类列表并注册 BeanDefinition 到 BeanDefinitionRegistry 中
reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
// 读取新的 BeanDefinitions
final String[] newCandidateNames = registry.getBeanDefinitionNames();
// 读取旧的 BeanDefinitions
final Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
final Set<String> alreadyParsedClasses = new HashSet<>();
// 将所有已解析的类名称写入 alreadyParsedClasses
for (final ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (final String candidateName : newCandidateNames) {
// 如果当前 BeanDefinition 是新解析的
if (!oldCandidateNames.contains(candidateName)) {
final BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
// 基于 BeanDefinition 创建 BeanDefinitionHolder 并将其写入 candidates
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
// 直到所有的配置类都解析完毕
while (!candidates.isEmpty());
// 注册 ImportRegistry bean 到 SingletonBeanRegistry 中
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) metadataReaderFactory).clearCache();
}
}
ConfigurationClassParser:配置类解析器
/**
* 解析所有配置类的 BeanDefinition
*/
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (final BeanDefinitionHolder holder : configCandidates) {
final BeanDefinition bd = holder.getBeanDefinition();
try {
// 1)如果此 BeanDefinition 来自 @Configuration 注解配置类
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 (final BeanDefinitionStoreException ex) {
throw ex;
}
catch (final Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
deferredImportSelectorHandler.process();
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
/**
* 解析单个配置类
*/
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
// 是否忽略此配置类
if (conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
// 此配置类是否已经解析过一次
final ConfigurationClass existingClass = configurationClasses.get(configClass);
if (existingClass != null) {
// 1)此配置类是导入的
if (configClass.isImported()) {
// 2)已经存在的配置类也是导入的
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.
*/
configurationClasses.remove(configClass);
knownSuperclasses.values().removeIf(configClass::equals);
}
}
/**
* 递归处理此配置类及其父类
* Recursively process the configuration class and its superclass hierarchy.
*/
SourceClass sourceClass = asSourceClass(configClass);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
// 写入已解析缓存
configurationClasses.put(configClass, configClass);
}
/**
* 基于 ConfigurationClass 创建 SourceClass
*/
private SourceClass asSourceClass(ConfigurationClass configurationClass) throws IOException {
// 读取注解元数据
final AnnotationMetadata metadata = configurationClass.getMetadata();
if (metadata instanceof StandardAnnotationMetadata) {
// 读取目标类
return asSourceClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
}
return asSourceClass(metadata.getClassName());
}
/**
* 基于 Class 创建 SourceClass
*/
SourceClass asSourceClass(@Nullable Class<?> classType) throws IOException {
if (classType == null) {
return new SourceClass(Object.class);
}
try {
/**
* 通过反射的方式读取注解的完整性测试,包括类属性
* Sanity test that we can reflectively read annotations,
* including Class attributes; if not -> fall back to ASM
*/
for (final Annotation ann : classType.getAnnotations()) {
AnnotationUtils.validateAnnotation(ann);
}
return new SourceClass(classType);
}
catch (final Throwable ex) {
// Enforce ASM via class name resolution
return asSourceClass(classType.getName());
}
}
/**
* 构建一个用于读取 BeanDefinition 的完整 ConfigurationClass
*/
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// 1)配置类上存在 Component 注解,则尝试递归处理其内部成员类
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
processMemberClasses(configClass, sourceClass);
}
/**
* 2)处理所有 @PropertySource 注解:将目标资源导入到 environment.propertySources 中
* 将所有的 @PropertySource 注解合并到 @PropertySources 注解中,并逐个进行处理
*/
for (final AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
/**
* 3)处理所有的 ComponentScan 注解
* 以深度优先的方式递归处理所有扫描到的配置类
*/
final Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
// 循环处理每个 ComponentScan 注解
for (final AnnotationAttributes componentScan : componentScans) {
// 如果此配置类存在 ComponentScan 注解,则通过 ComponentScanAnnotationParser 立即处理它
final Set<BeanDefinitionHolder> scannedBeanDefinitions =
componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 遍历扫描到的所有组件
for (final BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 如果此组件是一个配置类,则立即处理它
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
/**
* 4)处理所有的 @Import 注解
* 1)优先处理所有注解上的 @Import 注解导入的配置类
* 2)后处理此类上通过 @Import 注解直接导入的配置类
*/
processImports(configClass, sourceClass, getImports(sourceClass), true);
/**
* 5)处理所有的 @ImportResource 注解
*/
final AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
// 读取资源位置
final String[] resources = importResource.getStringArray("locations");
// 读取 BeanDefinitionReader
final Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (final String resource : resources) {
// 解析占位符
final String resolvedResource = environment.resolveRequiredPlaceholders(resource);
// 写入缓存
configClass.addImportedResource(resolvedResource, readerClass);
}
}
/**
* 6)处理所有的 @Bean 方法,将它们解析为 BeanMethod 并写入配置类中
*/
final Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (final MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 7)处理所有接口上非 Abstract 的 @Bean 方法
processInterfaces(configClass, sourceClass);
// 8)处理所有父类
if (sourceClass.getMetadata().hasSuperClass()) {
final String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!knownSuperclasses.containsKey(superclass)) {
// 已处理的父类缓存
knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// 此配置类处理完成
return null;
}
/**
* Register member (nested) classes that happen to be configuration classes themselves.
*/
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
// 读取所有的成员类
final Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
// 存在成员类
if (!memberClasses.isEmpty()) {
final List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
for (final SourceClass memberClass : memberClasses) {
// 过滤出所有的配置类
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
candidates.add(memberClass);
}
}
// 根据 Order 进行排序
OrderComparator.sort(candidates);
for (final SourceClass candidate : candidates) {
// 1)出现配置类循环导入
if (importStack.contains(configClass)) {
problemReporter.error(new CircularImportProblem(configClass, importStack));
}
else {
// 2)将此配置类入栈
importStack.push(configClass);
try {
// 处理此配置类
processConfigurationClass(candidate.asConfigClass(configClass));
}
finally {
// 3)解析完成后将其出栈
importStack.pop();
}
}
}
}
}
/**
* 处理给定的 @PropertySource 注解元数据
*/
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
// 读取名称
String name = propertySource.getString("name");
if (!StringUtils.hasLength(name)) {
name = null;
}
// 读取编码
String encoding = propertySource.getString("encoding");
if (!StringUtils.hasLength(encoding)) {
encoding = null;
}
// 读取资源位置
final String[] locations = propertySource.getStringArray("value");
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
// 读取资源未找到则忽略标识
final boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
// 读取 PropertySourceFactory
final Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
final PropertySourceFactory factory = factoryClass == PropertySourceFactory.class ?
DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass);
// 循环处理每个资源
for (final String location : locations) {
try {
// 解析占位符
final String resolvedLocation = environment.resolveRequiredPlaceholders(location);
// 读取资源
final Resource resource = resourceLoader.getResource(resolvedLocation);
// 创建 ResourcePropertySource 并加入到 environment 中
addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
}
catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {
// 占位符解析失败或资源未找到
if (ignoreResourceNotFound) {
if (logger.isInfoEnabled()) {
logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
}
}
else {
throw ex;
}
}
}
}
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
problemReporter.error(new CircularImportProblem(configClass, importStack));
}
else {
importStack.push(configClass);
try {
// 递归处理所有通过 @Import 导入的配置类
for (final SourceClass candidate : importCandidates) {
// 1)目标类是 ImportSelector 实例
if (candidate.isAssignable(ImportSelector.class)) {
final Class<?> candidateClass = candidate.loadClass();
// 创建目标实例
final ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
// 执行 BeanClassLoaderAware、BeanFactoryAware、EnvironmentAware、ResourceLoaderAware 注入
ParserStrategyUtils.invokeAwareMethods(
selector, environment, resourceLoader, registry);
if (selector instanceof DeferredImportSelector) {
deferredImportSelectorHandler.handle(
configClass, (DeferredImportSelector) selector);
}
else {
// 获取所有配置类名称
final String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
// 转换成 SourceClass 集合
final Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
// 递归处理所有导入的配置类
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
final Class<?> candidateClass = candidate.loadClass();
// 实例化 ImportBeanDefinitionRegistrar
final ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
// 执行 Aware 注入
ParserStrategyUtils.invokeAwareMethods(
registrar, environment, resourceLoader, registry);
// 写入 importBeanDefinitionRegistrars 缓存
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
/**
* 配置类不是 ImportSelector or ImportBeanDefinitionRegistrar,
* 则处理此配置类。
*/
importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (final BeanDefinitionStoreException ex) {
throw ex;
}
catch (final Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
importStack.pop();
}
}
}
/**
* 解析接口上的方法,如果此方法存在 @Bean 注解
*/
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
for (final SourceClass ifc : sourceClass.getInterfaces()) {
final Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
for (final MethodMetadata methodMetadata : beanMethods) {
if (!methodMetadata.isAbstract()) {
// A default method or other concrete method on a Java 8+ interface...
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
}
processInterfaces(configClass, ifc);
}
}
ConditionEvaluator:条件评估
/**
* 用于计算 @Conditional 注解的内部类
*/
class ConditionEvaluator {
private final ConditionContextImpl context;
public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
context = new ConditionContextImpl(registry, environment, resourceLoader);
}
/**
* 指定类或方法上是否存在 @Conditional 注解,并需要跳过处理流程
*/
public boolean shouldSkip(AnnotatedTypeMetadata metadata) {
return shouldSkip(metadata, null);
}
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
// 注解元数据为空 || 目标元素不存在 @Conditional 注解,不跳过
if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
return false;
}
if (phase == null) {
if (metadata instanceof AnnotationMetadata &&
ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
}
return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
}
final List<Condition> conditions = new ArrayList<>();
// 读取所有的条件类
for (final String[] conditionClasses : getConditionClasses(metadata)) {
for (final String conditionClass : conditionClasses) {
final Condition condition = getCondition(conditionClass, context.getClassLoader());
conditions.add(condition);
}
}
// 根据 Order 进行排序
AnnotationAwareOrderComparator.sort(conditions);
for (final Condition condition : conditions) {
ConfigurationPhase requiredPhase = null;
if (condition instanceof ConfigurationCondition) {
requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
}
// 请求阶段为空或请求阶段==此阶段 && 此条件不匹配
if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(context, metadata)) {
return true;
}
}
// 所有的条件都匹配
return false;
}
@SuppressWarnings("unchecked")
private List<String[]> getConditionClasses(AnnotatedTypeMetadata metadata) {
// 读取所有 @Conditional 注解的属性配置
final MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true);
// 读取评估条件
final Object values = attributes != null ? attributes.get("value") : null;
return (List<String[]>) (values != null ? values : Collections.emptyList());
}
/**
* 实例化目标条件
*/
private Condition getCondition(String conditionClassName, @Nullable ClassLoader classloader) {
final Class<?> conditionClass = ClassUtils.resolveClassName(conditionClassName, classloader);
return (Condition) BeanUtils.instantiateClass(conditionClass);
}
private static class ConditionContextImpl implements ConditionContext {
@Nullable
private final BeanDefinitionRegistry registry;
@Nullable
private final ConfigurableListableBeanFactory beanFactory;
private final Environment environment;
private final ResourceLoader resourceLoader;
@Nullable
private final ClassLoader classLoader;
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
this.registry = registry;
beanFactory = deduceBeanFactory(registry);
this.environment = environment != null ? environment : deduceEnvironment(registry);
this.resourceLoader = resourceLoader != null ? resourceLoader : deduceResourceLoader(registry);
classLoader = deduceClassLoader(resourceLoader, beanFactory);
}
@Nullable
private ConfigurableListableBeanFactory deduceBeanFactory(@Nullable BeanDefinitionRegistry source) {
if (source instanceof ConfigurableListableBeanFactory) {
return (ConfigurableListableBeanFactory) source;
}
if (source instanceof ConfigurableApplicationContext) {
return ((ConfigurableApplicationContext) source).getBeanFactory();
}
return null;
}
/**
* 推断 Environment
*/
private Environment deduceEnvironment(@Nullable BeanDefinitionRegistry source) {
if (source instanceof EnvironmentCapable) {
return ((EnvironmentCapable) source).getEnvironment();
}
return new StandardEnvironment();
}
/**
* 推断 ResourceLoader
*/
private ResourceLoader deduceResourceLoader(@Nullable BeanDefinitionRegistry source) {
if (source instanceof ResourceLoader) {
return (ResourceLoader) source;
}
return new DefaultResourceLoader();
}
/**
* 推断 ClassLoader
*/
@Nullable
private ClassLoader deduceClassLoader(@Nullable ResourceLoader resourceLoader,
@Nullable ConfigurableListableBeanFactory beanFactory) {
if (resourceLoader != null) {
final ClassLoader classLoader = resourceLoader.getClassLoader();
if (classLoader != null) {
return classLoader;
}
}
if (beanFactory != null) {
return beanFactory.getBeanClassLoader();
}
return ClassUtils.getDefaultClassLoader();
}
@Override
public BeanDefinitionRegistry getRegistry() {
Assert.state(registry != null, "No BeanDefinitionRegistry available");
return registry;
}
@Override
@Nullable
public ConfigurableListableBeanFactory getBeanFactory() {
return beanFactory;
}
@Override
public Environment getEnvironment() {
return environment;
}
@Override
public ResourceLoader getResourceLoader() {
return resourceLoader;
}
@Override
@Nullable
public ClassLoader getClassLoader() {
return classLoader;
}
}
}
- Condition:以 ConditionalOnProperty 为例
/**
* 此 Environment 中是否存在指定的属性 && 属性具有存在特定值【如果指定】。
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class) // 通过 @Conditional 注解关联条件类
public @interface ConditionalOnProperty {
/**
* 属性的名称
*/
String[] value() default {};
/**
* 每个属性的前缀
*/
String prefix() default "";
/**
* 属性的名称
*/
String[] name() default {};
/**
* 属性值
*/
String havingValue() default "";
/**
* 如果 Environment 中不存在此属性,是否匹配【默认不匹配】
*/
boolean matchIfMissing() default false;
}
/**
* 组件被注册到 BeanDefinitionRegistry 时必须满足的条件
*/
@FunctionalInterface
public interface Condition {
/**
* 判断此条件是否满足
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
public abstract class SpringBootCondition implements Condition {
private final Log logger = LogFactory.getLog(getClass());
@Override
public final boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {
// 读取类名或方法名称
String classOrMethodName = getClassOrMethodName(metadata);
try {
// 读取条件的输出结果
ConditionOutcome outcome = getMatchOutcome(context, metadata);
// 记录日志
logOutcome(classOrMethodName, outcome);
// 记录评估结果
recordEvaluation(context, classOrMethodName, outcome);
// 此条件是否满足
return outcome.isMatch();
}
catch (NoClassDefFoundError ex) {
throw new IllegalStateException(
"Could not evaluate condition on " + classOrMethodName + " due to "
+ ex.getMessage() + " not "
+ "found. Make sure your own configuration does not rely on "
+ "that class. This can also happen if you are "
+ "@ComponentScanning a springframework package (e.g. if you "
+ "put a @ComponentScan in the default package by mistake)",
ex);
}
catch (RuntimeException ex) {
throw new IllegalStateException(
"Error processing condition on " + getName(metadata), ex);
}
}
private String getName(AnnotatedTypeMetadata metadata) {
if (metadata instanceof AnnotationMetadata) {
return ((AnnotationMetadata) metadata).getClassName();
}
if (metadata instanceof MethodMetadata) {
MethodMetadata methodMetadata = (MethodMetadata) metadata;
return methodMetadata.getDeclaringClassName() + "."
+ methodMetadata.getMethodName();
}
return metadata.toString();
}
private static String getClassOrMethodName(AnnotatedTypeMetadata metadata) {
if (metadata instanceof ClassMetadata) {
ClassMetadata classMetadata = (ClassMetadata) metadata;
return classMetadata.getClassName();
}
MethodMetadata methodMetadata = (MethodMetadata) metadata;
return methodMetadata.getDeclaringClassName() + "#"
+ methodMetadata.getMethodName();
}
protected final void logOutcome(String classOrMethodName, ConditionOutcome outcome) {
if (this.logger.isTraceEnabled()) {
this.logger.trace(getLogMessage(classOrMethodName, outcome));
}
}
private StringBuilder getLogMessage(String classOrMethodName,
ConditionOutcome outcome) {
StringBuilder message = new StringBuilder();
message.append("Condition ");
message.append(ClassUtils.getShortName(getClass()));
message.append(" on ");
message.append(classOrMethodName);
message.append(outcome.isMatch() ? " matched" : " did not match");
if (StringUtils.hasLength(outcome.getMessage())) {
message.append(" due to ");
message.append(outcome.getMessage());
}
return message;
}
private void recordEvaluation(ConditionContext context, String classOrMethodName,
ConditionOutcome outcome) {
if (context.getBeanFactory() != null) {
ConditionEvaluationReport.get(context.getBeanFactory())
.recordConditionEvaluation(classOrMethodName, this, outcome);
}
}
/**
* 确定匹配结果
*/
public abstract ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata);
/**
* 只要有一个条件满足
*/
protected final boolean anyMatches(ConditionContext context,
AnnotatedTypeMetadata metadata, Condition... conditions) {
for (Condition condition : conditions) {
if (matches(context, metadata, condition)) {
return true;
}
}
return false;
}
/**
* 指定的条件是否满足
*/
protected final boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata, Condition condition) {
if (condition instanceof SpringBootCondition) {
return ((SpringBootCondition) condition).getMatchOutcome(context, metadata)
.isMatch();
}
return condition.matches(context, metadata);
}
}
/**
* 指定的属性是否定义在此 Environment 中
*/
@Order(Ordered.HIGHEST_PRECEDENCE + 40)
class OnPropertyCondition extends SpringBootCondition {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 读取目标元素上所有的 @ConditionalOnProperty 注解的属性信息
final List<AnnotationAttributes> allAnnotationAttributes = annotationAttributesFromMultiValueMap(
metadata.getAllAnnotationAttributes(ConditionalOnProperty.class.getName()));
final List<ConditionMessage> noMatch = new ArrayList<>();
final List<ConditionMessage> match = new ArrayList<>();
for (final AnnotationAttributes annotationAttributes : allAnnotationAttributes) {
// 确定当前 ConditionalOnProperty 条件的输出结果
final ConditionOutcome outcome = determineOutcome(annotationAttributes, context.getEnvironment());
// 记录 ConditionMessage
(outcome.isMatch() ? match : noMatch).add(outcome.getConditionMessage());
}
// 存在一个不匹配条件
if (!noMatch.isEmpty()) {
return ConditionOutcome.noMatch(ConditionMessage.of(noMatch));
}
// 所有的条件都匹配
return ConditionOutcome.match(ConditionMessage.of(match));
}
private List<AnnotationAttributes> annotationAttributesFromMultiValueMap(
MultiValueMap<String, Object> multiValueMap) {
final List<Map<String, Object>> maps = new ArrayList<>();
multiValueMap.forEach((key, value) -> {
for (int i = 0; i < value.size(); i++) {
Map<String, Object> map;
if (i < maps.size()) {
map = maps.get(i);
} else {
map = new HashMap<>();
maps.add(map);
}
map.put(key, value.get(i));
}
});
final List<AnnotationAttributes> annotationAttributes = new ArrayList<>(maps.size());
for (final Map<String, Object> map : maps) {
annotationAttributes.add(AnnotationAttributes.fromMap(map));
}
return annotationAttributes;
}
private ConditionOutcome determineOutcome(AnnotationAttributes annotationAttributes, PropertyResolver resolver) {
final Spec spec = new Spec(annotationAttributes);
final List<String> missingProperties = new ArrayList<>();
final List<String> nonMatchingProperties = new ArrayList<>();
spec.collectProperties(resolver, missingProperties, nonMatchingProperties);
// 1)属性值不存在
if (!missingProperties.isEmpty()) {
return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, spec)
.didNotFind("property", "properties").items(Style.QUOTE, missingProperties));
}
// 2)属性值存在,但是不匹配
if (!nonMatchingProperties.isEmpty()) {
return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, spec)
.found("different value in property", "different value in properties")
.items(Style.QUOTE, nonMatchingProperties));
}
// 此 ConditionalOnProperty 条件匹配
return ConditionOutcome
.match(ConditionMessage.forCondition(ConditionalOnProperty.class, spec).because("matched"));
}
private static class Spec {
private final String prefix;
private final String havingValue;
private final String[] names;
private final boolean matchIfMissing;
Spec(AnnotationAttributes annotationAttributes) {
// 读取 ConditionalOnProperty 注解的 prefix 属性
String prefix = annotationAttributes.getString("prefix").trim();
// prefix 不为空,则尝试添加 . 后缀
if (StringUtils.hasText(prefix) && !prefix.endsWith(".")) {
prefix = prefix + ".";
}
this.prefix = prefix;
// 读取 ConditionalOnProperty 注解的 havingValue 属性
havingValue = annotationAttributes.getString("havingValue");
// 读取 ConditionalOnProperty 注解的关联属性名称
names = getNames(annotationAttributes);
// 读取 ConditionalOnProperty 注解的 matchIfMissing 属性
matchIfMissing = annotationAttributes.getBoolean("matchIfMissing");
}
private String[] getNames(Map<String, Object> annotationAttributes) {
final String[] value = (String[]) annotationAttributes.get("value");
final String[] name = (String[]) annotationAttributes.get("name");
Assert.state(value.length > 0 || name.length > 0,
"The name or value attribute of @ConditionalOnProperty must be specified");
Assert.state(value.length == 0 || name.length == 0,
"The name and value attributes of @ConditionalOnProperty are exclusive");
// value 属性的优先级高于 name
return value.length > 0 ? value : name;
}
private void collectProperties(PropertyResolver resolver, List<String> missing, List<String> nonMatching) {
// 遍历所有的属性名称
for (final String name : names) {
// 添加前缀
final String key = prefix + name;
// 1)如果 Environment 中存在此属性
if (resolver.containsProperty(key)) {
// 指定的值不匹配,则写入 nonMatching 中
if (!isMatch(resolver.getProperty(key), havingValue)) {
nonMatching.add(name);
}
// 2)Environment 中不存在此属性
} else {
// 如果不能忽略此属性,则写入 missing 中
if (!matchIfMissing) {
missing.add(name);
}
}
}
}
private boolean isMatch(String value, String requiredValue) {
// 1)指定了必须的值,则使用 equals 进行比较
if (StringUtils.hasLength(requiredValue)) {
return requiredValue.equalsIgnoreCase(value);
}
// 只要属性值不是忽略大小写的 false,就匹配
return !"false".equalsIgnoreCase(value);
}
@Override
public String toString() {
final StringBuilder result = new StringBuilder();
result.append("(");
result.append(prefix);
if (names.length == 1) {
result.append(names[0]);
} else {
result.append("[");
result.append(StringUtils.arrayToCommaDelimitedString(names));
result.append("]");
}
if (StringUtils.hasLength(havingValue)) {
result.append("=").append(havingValue);
}
result.append(")");
return result.toString();
}
}
}
ComponentScanAnnotationParser
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
/**
* 基础包名称
*/
@AliasFor("basePackages")
String[] value() default {};
/**
* 基础包名称
*/
@AliasFor("value")
String[] basePackages() default {};
/**
* 基础包类【读取指定类所在的包路径】
*/
Class<?>[] basePackageClasses() default {};
/**
* 用于生成 bean 名称的 BeanNameGenerator
*/
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
/**
* 范围解析器
*/
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
/**
* 是否需要为目标组件生成代理,默认不生成
*/
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
/**
* 资源模式
*/
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
/**
* 是否使用默认的过滤器
* 自动检测 @Component、@Repository、@Service、@Controller 注解标注的类
*/
boolean useDefaultFilters() default true;
/**
* 指定扫描哪些类型
*/
Filter[] includeFilters() default {};
/**
* 指定排除哪些类型
*/
Filter[] excludeFilters() default {};
/**
* 扫描到的单例 bean 是否需要延迟初始化
*/
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
/**
* 过滤类型,默认是基于注解
*/
FilterType type() default FilterType.ANNOTATION;
/**
* 用作筛选器的类,多个类之间是逻辑或的关系
*/
@AliasFor("classes")
Class<?>[] value() default {};
/**
* 用作筛选器的类,多个类之间是逻辑或的关系
*/
@AliasFor("value")
Class<?>[] classes() default {};
/**
* 匹配模式,根据 FilterType 分流
*/
String[] pattern() default {};
}
}
- ComponentScanAnnotationParser:ComponentScan 注解解析器
/**
* @ComponentScan 注解解析器
*/
class ComponentScanAnnotationParser {
private final Environment environment;
private final ResourceLoader resourceLoader;
private final BeanNameGenerator beanNameGenerator;
private final BeanDefinitionRegistry registry;
public ComponentScanAnnotationParser(Environment environment, ResourceLoader resourceLoader,
BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry) {
this.environment = environment;
this.resourceLoader = resourceLoader;
this.beanNameGenerator = beanNameGenerator;
this.registry = registry;
}
/**
* 解析指定的 @ComponentScan 注解
*/
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
// 类路径 BeanDefinition 扫描器
final ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry,
componentScan.getBoolean("useDefaultFilters"), environment, resourceLoader);
// 设置扫描器的 BeanNameGenerator
final Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
final boolean useInheritedGenerator = BeanNameGenerator.class == generatorClass;
scanner.setBeanNameGenerator(useInheritedGenerator ? beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
// 尝试设置扫描器的 ScopedProxyMode
final ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
final Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
// 设置扫描器的资源模式
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
// 添加包含过滤器,默认无
for (final AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (final TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
// 添加排序过滤器
for (final AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (final TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
// 设置延迟初始化属性
final boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
final Set<String> basePackages = new LinkedHashSet<>();
// 尝试读取 basePackages 属性
final String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (final String pkg : basePackagesArray) {
// 解析占位符,并按照 ,;\t\n 切割包路径
final String[] tokenized = StringUtils.tokenizeToStringArray(environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
// 读取 basePackageClasses,并提取出包路径
for (final Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
/**
* 如果 basePackages 和 basePackageClasses 都未配置,
* 则以 @ComponentScan 注解所在配置类的包路径作为基础包
*/
if (basePackages.isEmpty()) {
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 List<TypeFilter> typeFiltersFor(AnnotationAttributes filterAttributes) {
final List<TypeFilter> typeFilters = new ArrayList<>();
// 读取过滤类型
final FilterType filterType = filterAttributes.getEnum("type");
// 读取所有的 classes
for (final Class<?> filterClass : filterAttributes.getClassArray("classes")) {
switch (filterType) {
// 1)过滤类型为基于注解
case ANNOTATION:
// 目标 class 是否是注解
Assert.isAssignable(Annotation.class, filterClass,
"@ComponentScan ANNOTATION type filter requires an annotation type");
@SuppressWarnings("unchecked") final
Class<Annotation> annotationType = (Class<Annotation>) filterClass;
// 添加注解类型过滤器
typeFilters.add(new AnnotationTypeFilter(annotationType));
break;
// 2)过滤类型为基于目标类型及其子类
case ASSIGNABLE_TYPE:
// 添加类型过滤器
typeFilters.add(new AssignableTypeFilter(filterClass));
break;
// 3)过滤类型为基于自定义过滤器
case CUSTOM:
// 添加自定义 TypeFilter
Assert.isAssignable(TypeFilter.class, filterClass,
"@ComponentScan CUSTOM type filter requires a TypeFilter implementation");
final TypeFilter filter = BeanUtils.instantiateClass(filterClass, TypeFilter.class);
ParserStrategyUtils.invokeAwareMethods(
filter, environment, resourceLoader, registry);
typeFilters.add(filter);
break;
default:
throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType);
}
}
// 如果指定了匹配模式
for (final String expression : filterAttributes.getStringArray("pattern")) {
switch (filterType) {
// 过滤类型为 ASPECTJ
case ASPECTJ:
typeFilters.add(new AspectJTypeFilter(expression, resourceLoader.getClassLoader()));
break;
// 过滤类型为 REGEX
case REGEX:
typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression)));
break;
default:
throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType);
}
}
return typeFilters;
}
}
ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner#
/**
* 执行包扫描
*/
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
final Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (final String basePackage : basePackages) {
// 查找所有的注解组件
final Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (final BeanDefinition candidate : candidates) {
// 写入 Scope
final ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
final String beanName = beanNameGenerator.generateBeanName(candidate, registry);
if (candidate instanceof AbstractBeanDefinition) {
// 应用默认配置
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 处理 BeanDefinition 相关注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 指定 beanName 的 BeanDefinition 不存在
if (checkCandidate(beanName, candidate)) {
// 创建 BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 尝试应用代理模式
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, registry);
// 添加到 beanDefinitions 进行循环处理
beanDefinitions.add(definitionHolder);
// 注册此 BeanDefinition 到 BeanDefinitionRegistry 中
registerBeanDefinition(definitionHolder, registry);
}
}
}
return beanDefinitions;
}
AnnotationConfigUtils#
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
processCommonDefinitionAnnotations(abd, abd.getMetadata());
}
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
// 1)目标元素存在 @Lazy 注解
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
// 2)目标元素存在 @Primary 注解
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
// 3)目标元素存在 @DependsOn 注解
final AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
// 4)目标元素存在 @Role 注解
final AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
abd.setRole(role.getNumber("value").intValue());
}
// 5)目标元素存在 @Description 注解
final AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
abd.setDescription(description.getString("value"));
}
}
static BeanDefinitionHolder applyScopedProxyMode(
ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
// 读取代理模式
final ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
return definition;
}
// 如果是基于 CGLIB 的类代理
final boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
ClassPathScanningCandidateComponentProvider#
/**
* 扫描指定的类路径
*/
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(componentsIndex, basePackage);
}
else {
// 扫描组件
return scanCandidateComponents(basePackage);
}
}
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
final Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// classpath*:org/zxd/spring5/**/*.class
final String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + resourcePattern;
// 通过 ServletContextResourcePatternResolver 读取所有资源
final Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
final boolean traceEnabled = logger.isTraceEnabled();
final boolean debugEnabled = logger.isDebugEnabled();
// 循环处理所有资源
for (final Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
// 资源是可读取的
if (resource.isReadable()) {
try {
// 读取 MetadataReader
final MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
// 当前资源是否是候选组件
if (isCandidateComponent(metadataReader)) {
// 基于 MetadataReader 创建 ScannedGenericBeanDefinition
final 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 (final Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
}
catch (final IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
/**
* 将类名解析为资源路径
* 为了避免多余的替换操作,可以直接使用 / 作为包分隔符
*/
protected String resolveBasePackage(String basePackage) {
return ClassUtils.convertClassNameToResourcePath(getEnvironment().resolveRequiredPlaceholders(basePackage));
}
/**
* 目标类不匹配任何排除过滤器,并且至少匹配一个包含过滤器
*/
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (final TypeFilter tf : excludeFilters) {
// 匹配当期排除过滤器
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
for (final TypeFilter tf : includeFilters) {
// 匹配当前包含过滤器
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return isConditionMatch(metadataReader);
}
}
return false;
}
/**
* 目标 BeanDefinition 是否是一个候选组件
*/
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
final AnnotationMetadata metadata = beanDefinition.getMetadata();
/**
* 目标类型不是接口,并且不依赖于封闭类【不是内部类】
*/
return metadata.isIndependent() && (metadata.isConcrete() ||
metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()));
}
ServletContextResourcePatternResolver
ServletContextResourcePatternResolver#
/**
* 可配置 ServletContext 的 PathMatchingResourcePatternResolver
*/
public class ServletContextResourcePatternResolver extends PathMatchingResourcePatternResolver {
private static final Log logger = LogFactory.getLog(ServletContextResourcePatternResolver.class);
public ServletContextResourcePatternResolver(ServletContext servletContext) {
super(new ServletContextResourceLoader(servletContext));
}
public ServletContextResourcePatternResolver(ResourceLoader resourceLoader) {
super(resourceLoader);
}
@Override
protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern)
throws IOException {
// 如果跟路径资源是 ServletContextResource
if (rootDirResource instanceof ServletContextResource) {
final ServletContextResource scResource = (ServletContextResource) rootDirResource;
final ServletContext sc = scResource.getServletContext();
final String fullPattern = scResource.getPath() + subPattern;
final Set<Resource> result = new LinkedHashSet<>(8);
doRetrieveMatchingServletContextResources(sc, fullPattern, scResource.getPath(), result);
return result;
}
else {
// 默认是 UrlResource
return super.doFindPathMatchingFileResources(rootDirResource, subPattern);
}
}
}
PathMatchingResourcePatternResolver#
@Override
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)
* 资源路径是 Ant 风格的通配符
*/
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
// a class path resource pattern
return findPathMatchingResources(locationPattern);
}
else {
// 读取 classpath 特定根路径下的所有资源
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.
final 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)};
}
}
}
/**
* 通过 Ant 风格的路径匹配器查找所有匹配资源
*/
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
// 确定给定位置的根目录:classpath*:org/zxd/spring5/
final String rootDirPath = determineRootDir(locationPattern);
// 截取模糊匹配路径:**/*.class
final String subPattern = locationPattern.substring(rootDirPath.length());
// 读取根路径 Resource
final Resource[] rootDirResources = getResources(rootDirPath);
final Set<Resource> result = new LinkedHashSet<>(16);
// 遍历所有根路径
for (Resource rootDirResource : rootDirResources) {
rootDirResource = resolveRootDirResource(rootDirResource);
// 获取根路径 URL
URL rootDirUrl = rootDirResource.getURL();
// 1)URL 协议以 bundle 开头
if (equinoxResolveMethod != null && rootDirUrl.getProtocol().startsWith("bundle")) {
final URL resolvedUrl = (URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, rootDirUrl);
if (resolvedUrl != null) {
rootDirUrl = resolvedUrl;
}
rootDirResource = new UrlResource(rootDirUrl);
}
// 2)URL 协议以 vfs 开头
if (rootDirUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirUrl, subPattern, getPathMatcher()));
}
// 3)URL 是一个 jar:jar、war、zip、vfszip、wsjar
else if (ResourceUtils.isJarURL(rootDirUrl) || isJarResource(rootDirResource)) {
result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirUrl, subPattern));
}
else {
// 4)URL 协议以 file 开头
result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
}
}
if (logger.isTraceEnabled()) {
logger.trace("Resolved location pattern [" + locationPattern + "] to resources " + result);
}
return result.toArray(new Resource[0]);
}
protected Resource[] findAllClassPathResources(String location) throws IOException {
String path = location;
if (path.startsWith("/")) {
path = path.substring(1);
}
// 读取所有的 ClassPathResource
final Set<Resource> result = doFindAllClassPathResources(path);
if (logger.isTraceEnabled()) {
logger.trace("Resolved classpath location [" + location + "] to resources " + result);
}
return result.toArray(new Resource[0]);
}
protected Set<Resource> doFindAllClassPathResources(String path) throws IOException {
final Set<Resource> result = new LinkedHashSet<>(16);
// 读取类加载器
final ClassLoader cl = getClassLoader();
// 读取指定包路径【org/zxd/spring5/】下所有资源的 URL
final Enumeration<URL> resourceUrls = cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path);
while (resourceUrls.hasMoreElements()) {
final URL url = resourceUrls.nextElement();
result.add(convertClassLoaderURL(url));
}
if ("".equals(path)) {
// The above result is likely to be incomplete, i.e. only containing file system references.
// We need to have pointers to each of the jar files on the classpath as well...
addAllClassLoaderJarRoots(cl, result);
}
return result;
}
/**
* 将 URL 转换为 UrlResource
*/
protected Resource convertClassLoaderURL(URL url) {
return new UrlResource(url);
}