这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战
7. 详细研究四次调用中的第一次调用. 通过分析跟踪@ComponentScan注解是如何解析的,
通过跟踪@ComponentScan注解是如何解析的, 分来理解BeanDefinitionScan, BeanDefinitionRegistry, BeanDefinitionReader是如何工作的.
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
/**
* 首先,调用BeanDefinitionRegistryPostProcessors 的后置处理器
* 定义已处理的后置处理器
*/
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
/**
* 这里一共分为两大步:
* 第一步: 调用所有实现了 BeanDefinitionRegistryPostProcessor 接口的bean定义. (BeanDefinitionRegistryPostProcessor带注册功能的后置处理器)
* 第二步: 调用BeanFactoryPostProcessor Bean工厂的后置处理器
*/
/**********************第一步: 调用所有实现了BeanDefinitionRegistryPostProcessor接口的bean定义 begin****************************/
// 判断beanFactory是否实现了BeanDefinitionRegistry, 实现了该结构就有注册和获取Bean定义的能力
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
/**
* 这是一个集合, 存马上即将要被调用的BeanDefinitionRegistryPostProcessor
*/
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 首先, 调用实现了PriorityOrdered的BeanDefinitionRegistryPostProcessors
// 在所有创世纪的后置处理器中, 只有 internalConfigurationAnnotationProcessor 实现了 BeanDefinitionRegistryPostProcessors 和 PriorityOrdered
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 判断beanFactory是否实现了PriorityOrdered接口. 如果实现了,是最优先调用.
// 在整个加载过程中,会调用四次BeanDefinitionRegistryPostProcessor, 而实现了PriorityOrdered的接口最先调用
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 调用beanFactory.getBean实例化配置类的后置处理器(创世界的类ppName), 也就是初始化, 实例化, 赋值属性.
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class ) );
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
/**
* 第一次调用BeanDefinitionRegistryPostProcessors
* 在这里典型的BeanDefinitionRegistryPostProcessors就是ConfigurationClassPostProcessor
* 用于进行bean定义的加载 比如我们的包扫描 @import 等
*/ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 处理完了,清空currentRegistryProcessors
currentRegistryProcessors.clear();
这里也有两大步
第一步: 初始化bean工厂的后置处理器
通过调用beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class ) 初始化了bean工厂的后置处理器,
第二步: 解析配置
调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);调用beanDefinitionRegistry的后置处理器. 筛选出符合条件的配置类.
如上图所示, 最后筛选出的配置类只有MainConfig配置类. 也就是说configCandidates配置候选集合中只有一个MainConfig
// 创建一个ConfigurationClassParser对象, 解析@Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this .componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 执行解析 parser.parse(candidates);
parser.validate();
然后, 接下来创建了一个对象ConfigurationClassParser, 这是一个配置类解析器. 下面将使用这个解析器解析配置类.
重点是如何解析的, 代码已重点标注出来了.
// 执行解析
parser.parse(candidates);
我们这里是通过注解解析的, 所以直接看下面的代码
public void parse(Set<BeanDefinitionHolder> configCandidates) {
// 循环配置类
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
// 真正的解析bean定义:通过注解元数据解析
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
......
}
解析主要做了几件事呢?如下图:
解析配置类, 看看配置类是否含有如上标记的注解, 如果有, 则调用响应的返回对其进行解析,处理.
下面来看看源码. 是如何处理这一块的.
/**
* 在这里会解析@Component @PropertySources @ComponentScan @ImportResource
* @param configClass
* @param sourceClass
* @param filter
* @return
* @throws IOException
*/
@Nullable
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
// 1. 处理@Component注解,判断元数据是否带有Component注解
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
// Process any @PropertySource annotations
// 2. 处理@PropertySource 注解, 判断元数据是否带有@PropertySource注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
// 3. 处理@ComponentScan注解, 判断元数据是否带有@ComponentScan注解
/**
* 这里mainConfig配置类中有两个注解,一个是@Configuration ,一个是@ComponentScan. 在这里, 我们看一下@ComponentScan
*/
//componentScans 拿到的就是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) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 解析扫描出来的类, 将其解析为BeanDefinitionHolder对象, 并放入到scannedBeanDefinitions中
// 这正的解析ComponentScans和ComponentScan中的配置
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 循环处理包扫描出来的bean定义
// Check the set of scanned definitions for any further config classes and parse recursively if needed
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());
}
}
}
}
// 4. 处理@Import注解 // Process any @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 5. 处理@ImportResource注解 // Process any @ImportResource annotations
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 6. 处理@Bean注解 // Process individual @Bean methods
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 处理默认方法
// Process default methods on interfaces
processInterfaces(configClass, sourceClass);
// 处理超类
// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
下面我们重点看对@ComponentScan和@ComponentScans注解的解析, 为什么看他呢? 因为很多注解都标记了@Component注解.
比如@Service注解,本身使用@Component
再来看@Controller注解, 其实质也是一个@Component注解
我们在自定义配置类的时候, 会使用@ComponentScan注解. 并传递一个包, 作为扫描包. 如MainConfig配置
这就会扫描包下所有的配置类.
它主要的逻辑如下:
在拿到@ComponentScan注解以后, 会对其进行parse. 主要解析里面的注解. 并对每一个注解进行处理. 处理后将其添加到scanner属性中. 最后调用scanner.doScan(....)方法.
源码如下:
// 解析配置
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
// 定义了一个类路径扫描器ClassPathBeanDefinitionScanner // 这里的scanner用于读取配置类
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); // 1. 判断是否有nameGenerator注解 // 为扫描器设置beanName的生成器对象, 并赋值给scanner, BeanNameGenerator的作用是为bean definitions生成Bean名字的接口
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
// 2. 判断是否有scopedProxy注解
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));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
// 3. 判断属性中是否有includeFilters属性, 有的话就添加到scanner中 // 设置componentScan中包含的过滤器 -- 在使用注解的时候配置了包含和排除的过滤器, 这里进行处理
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
// 4. 判断属性总是否有excludeFilters属性, 有的话放到scnanner中 // 设置componentScan中排除的过滤器
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
// 5. 判断是否有lazyInit属性 // 获取配置类中懒加载初始化的属性
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
Set<String> basePackages = new LinkedHashSet<>();
// 6. 判断是否有basePackages属性 // 获取basePackages属性, 也就是我们定义的包扫描路径
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()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
// 调用scanner.doScan()方法, 扫描basePackages包
return scanner.doScan( StringUtils.toStringArray(basePackages));
}
调用doScan方法扫描配置类. 我们来看看主要做了哪些事情
第一步: 找到所有候选的BeanDefinition.
上面解析出了@ComponentScan注解传递过来的basePackages包. 扫描包中所有的类, 得到候选类.
扫描的时候做了几件事呢? 看最上图最右侧部分. 这扫描出来就是我们的目标类.
第二步: 解析这些准目标类.
第三步: 设置默认的beanDefinition属性
/**
* 设置默认的bean定义的信息
* Apply the provided default values to this bean.
* @param defaults the default settings to apply
* @since 2.5
*/
public void applyDefaults(BeanDefinitionDefaults defaults) {
// 设置这个类是不是懒加载的
Boolean lazyInit = defaults.getLazyInit();
if (lazyInit != null) {
setLazyInit(lazyInit);
}
// 设置默认的自动装配方式
setAutowireMode(defaults.getAutowireMode());
setDependencyCheck(defaults.getDependencyCheck());
// 设置初始化方法的名称
setInitMethodName(defaults.getInitMethodName());
// 是否可以调用InitMethod方法
setEnforceInitMethod(false);
setDestroyMethodName(defaults.getDestroyMethodName());
// 是否可以调用DestroyMethod方法
setEnforceDestroyMethod(false);
}
第四步: 将解析出来的bean定义注册到ioc容器中
这里就调用了BeanDefinitionReaderUtils.registerBeanDefinition注册bean定义. 之前注册过配置类, 这里和其是一样的. 所以不再赘述了
这里有两个细节:
- excludeFilter中排除了自己
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
// 定义了一个类路径扫描器ClassPathBeanDefinitionScanner
// 这里的scanner用于读取配置类
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
// 1. 判断是否有nameGenerator注解
// 为扫描器设置beanName的生成器对象
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
// 2. 判断是否有scopedProxy注解
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));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
// 3. 判断属性中是否有includeFilters属性, 有的话就添加到scanner中
// 设置componentScan中包含的过滤器 -- 在使用注解的时候配置了包含和排除的过滤器, 这里进行处理
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
// 4. 判断属性总是否有excludeFilters属性, 有的话放到scnanner中
// 设置componentScan中排除的过滤器
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
// 5. 判断是否有lazyInit属性
// 获取配置类中懒加载初始化的属性
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
Set<String> basePackages = new LinkedHashSet<>();
// 6. 判断是否有basePackages属性
// 获取basePackages属性, 也就是我们定义的包扫描路径
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()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
// 想ExcludeFilter中添加默认的排除类,
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
/**
* declaringClass就是配置类MainConfig, 也就是说. 如果当前类是配置类, 那么就会排除掉
* 这是一个钩子方法, 现在不会调用. 后面才调用
* 在哪里调用呢?
*/
return declaringClass.equals(className);
}
}); // 调用scanner.doScan()方法, 扫描basePackages包
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
在解析配置类的时候, 除了@ComponentScan注解中定义的ExcludeFilter和IncludeFilter以外, 还有默认的排除类. 如上加粗字体的部分. 这里是排除了配置类本身, 我们这里的配置类是MainConfig, 也就说, 会排除掉自己.
@Override
protected boolean matchClassName(String className) {
/**
* declaringClass就是配置类MainConfig, 也就是说. 如果当前类是配置类, 那么就会排除掉
* 这是一个钩子方法, 现在不会调用. 后面才调用
* 在哪里调用呢? 先记住这个钩子方法matchClassName
*/
return declaringClass.equals(className);
}
matchClassName是一个钩子方法. 在执行到这里的时候, 不会真的去执行. 什么时候执行呢? 后面调用doScan的时候执行.
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
// 循环包路径
for (String basePackage : basePackages) {
// 第一步: 找到所有候选的BeanDefinition
/**
* 在候选的配置类中, 排除掉了自己, 同时包含了默认的配置类
*/ Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
// 扫描basePackages, 获取候选类
return scanCandidateComponents(basePackage);
}
}
进入这个方法
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
//第一步: 将com.lxl.www.iocbeanlifecicle转换成了物理路径com/lxl/www/iocbeanlifecicle
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//第二步: .getResources(...)读取到了包下所有的类
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)) { // 通过scnner扫描出来的beanDefinition是ScannedGenericBeanDefinition类型
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
// 设置sbd的原类路径
sbd.setSource(resource);
在第四步的时候调用了isCandidateComponent(metadataReader, 这里就判断了是否是包含的类,或者是排除的类
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
// 判断这个类类是否是我们设置的要排除的?
// 这里依然使用到了策略设计模式. TypeFilter是一个父类, 不同子类的TypeFilter会调用不同的match方法
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;
}
紫色加错的部分是就是判读是否符合排除的类. 红色加错的部分是判断是否是包含的类.
先来看紫色的部分, 排除的类
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// This method optimizes avoiding unnecessary creation of ClassReaders
// as well as visiting over those readers.
if (matchSelf(metadataReader)) {
return true;
}
ClassMetadata metadata = metadataReader.getClassMetadata();
// 排除配置类.
if (matchClassName(metadata.getClassName())) {
return true;
}
看到了么, 这里调用了matchClassName. 这就是上面定义的钩子方法,
@Override
protected boolean matchClassName(String className) {
/**
* declaringClass就是配置类MainConfig, 也就是说. 如果当前类是配置类, 那么就会排除掉
* 这是一个钩子方法, 现在不会调用. 后面才调用
* 在哪里调用呢? 先记住这个钩子方法matchClassName
*/
return declaringClass.equals(className);
}
此时declaringClass表示的是当前的配置类, className表示的是目标类, 如果当前目标类 == 配置类, 那么就放回true. 返回true, 则会排除掉
- includeFilter中包含了默认的配置类
下面来看红色加错的部分
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
// 判断这个类类是否是我们设置的要排除的?
// 这里依然使用到了策略设计模式. TypeFilter是一个父类, 不同子类的TypeFilter会调用不同的match方法
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;
}
我们看到这里有this.includeFilters.包含的过滤器. 这里面是有值的
我们没有在配置类MainConfig上设置includeFilter啊, 这里面怎么会有值呢?
这是因为我们有默认包含的过滤器, 下面看看默认包含的过滤器是在哪里设置的.
首先从入口类点击AnnotationConfigApplicationContextxt
然后在点击this();
再点击ClassPathBeanDefinitionScanner
然后一路点击三个this(...)
最后看到上图 registerDefaultFilter();注册默认的过滤器
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
// 注册默认的filter---第一个: 在includeFilter中增加了Component
this.includeFilters.add(new AnnotationTypeFilter(Component.class ));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
// 注册默认的filter---第二个:在includeFilter中增加了 javax.annotation.ManagedBean
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 {
// 注册默认的filter---第三个:在includeFilter中增加了 javax.inject.Named
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.
}
}
如上图看到, 注册了3个默认的过滤器. 分别是Component, ManagedBean, Named. 他们都是注解类型的过滤器AnnotationTypeFilter
其中javax.annotation.ManagedBean和 javax.inject.Named是jdk提供给我们的.