注解相关的
自动扫描
xml配置下的
<context:component-scan/>
spring.handler查找到对应的element handler为 ContextNamespaceHandler,parser:ComponentScanBeanDefinitionParser
类解析ComponentScanBeanDefinitionParser
//ComponentScanBeanDefinitionParser
public BeanDefinition parse(Element element, ParserContext parserContext) {
String[] basePackages = StringUtils.tokenizeToStringArray(element.getAttribute(BASE_PACKAGE_ATTRIBUTE),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// Actually scan for bean definitions and register them.
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
//扫描并注册
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
XmlReaderContext readerContext = parserContext.getReaderContext();
boolean useDefaultFilters = true;
if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
}
// Delegate bean definition registration to scanner class.,设置<beans>上的一些参数给scanner
ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters);
scanner.setResourceLoader(readerContext.getResourceLoader());
scanner.setEnvironment(parserContext.getDelegate().getEnvironment());
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
}
try {
//自动扫描类名称生成器
parseBeanNameGenerator(element, scanner);
} catch (Exception ex) {
readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
}
try {
//处理scope注解和scope解析器
parseScope(element, scanner);
} catch (Exception ex) {
readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause());
}
//设置type过滤器
parseTypeFilters(element, scanner, readerContext, parserContext);
return scanner;
}
ComponentScan是自动扫描class文件生成beanDefinition,那么该类肯定会提供设置beanDefinition相关属性的功能.包括scope,nameGenerator,类过滤器等.
<context:component-scan base-package="" resource-pattern="" annotation-config="" scoped-proxy=""/>
其中resource-pattern设置class的匹配模式,使用的是ant分隔,baseDir是base-package指定.
componentScanner将扫描出来的resource封装成SimpleMetadataReader来进行过滤判断.
SimpleMetadataReader 内部实际上使用asm将class文件解析成一个class信息树.
ClassPathBeanDefinitionScanner 内部定义的beanNameGenerator(AnnotationBeanNameGenerator)和ScopeMetadataResolver(AnnotationScopeMetadataResolver) 默认支持继承@Component和@Scopse注解, 自定义的@Component 支持value属性.因为componentScanner 扫描出来的beanDefiniton是ScannedGenericBeanDefinition,本身继承AnnotatedBeanDefinition.
注解启用
<context:componentscan/>可以在解析该节点的时候就扫描所有的component,但是使用注解处理的情况下会这么办.是在合适执行扫描操作呢.是什么时候处理该注解的呢?
ConfigurationClassPostProcessor 处理@Configuration注解
ConfigurationClassPostProcessor 继承 BeanDefinitionRegistryPostProcessor,
BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor ,
这两个接口本质上一样(都是在所有的beanDefinition 加载完成后再次对BeanFactory 和 BeanDefinitionRegistry进行二次处理). 只是执行先后顺序不一样.
因为ConfigurationClassPostProcessor的作用是加载新的BeanDefinition,所有默认应该实现 BeanDefinitionRegistryPostProcessor 的方法.
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
//注册 ImportAwareBeanPostProcessor 的BeanPostProcessor
RootBeanDefinition iabpp = new RootBeanDefinition(ImportAwareBeanPostProcessor.class);
iabpp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(IMPORT_AWARE_PROCESSOR_BEAN_NAME, iabpp);
RootBeanDefinition ecbpp = new RootBeanDefinition(EnhancedConfigurationBeanPostProcessor.class);
ecbpp.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(ENHANCED_CONFIGURATION_PROCESSOR_BEAN_NAME, ecbpp);
//重复执行检测
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called for this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
//核心处理方法
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
Set<BeanDefinitionHolder> configCandidates = new LinkedHashSet<BeanDefinitionHolder>();
//遍历所有的beanDefinition
for (String beanName : registry.getBeanDefinitionNames()) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//是否已经处理过改beanDefinition
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//如果是候选类,
//full候选类, 有@Configuration注解的
//lite 带有@Import , @Component , 有@Bean方法的.(那几乎是所有的BeanDefintion都满足)
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
//如果没有立即返回
if (configCandidates.isEmpty()) {
return;
}
// Detect any custom bean name generation strategy supplied through the enclosing application context
//探测手动注册的BeanNameGenerator单例(名称固定)
SingletonBeanRegistry singletonRegistry = null;
if (registry instanceof SingletonBeanRegistry) {
singletonRegistry = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet && singletonRegistry.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
BeanNameGenerator generator = (BeanNameGenerator) singletonRegistry.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//核心解析方法.
parser.parse(configCandidates);
parser.validate();
// Handle any @PropertySource annotations
List<PropertySource<?>> parsedPropertySources = parser.getPropertySources();
if (!parsedPropertySources.isEmpty()) {
if (!(this.environment instanceof ConfigurableEnvironment)) {
logger.warn("Ignoring @PropertySource annotations. " +
"Reason: Environment must implement ConfigurableEnvironment");
}
else {
MutablePropertySources envPropertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
for (PropertySource<?> propertySource : parsedPropertySources) {
envPropertySources.addLast(propertySource);
}
}
}
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor,
this.problemReporter, this.metadataReaderFactory, this.resourceLoader, this.environment,
this.importBeanNameGenerator);
}
this.reader.loadBeanDefinitions(parser.getConfigurationClasses());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (singletonRegistry != null) {
if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
ConfigurationClassParser.parse
//org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
//遍历循环每一个类,并解析
if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
//存在class的直接解析class,反射
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
//否则通过className来解析(asm),
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("Failed to load bean class: " + bd.getBeanClassName(), ex);
}
}
processDeferredImportSelectors();
}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
//同一个configuration类被多次处理,可能原因通过import导入的
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);
for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext(); ) {
if (configClass.equals(it.next())) {
it.remove();
}
}
}
}
// Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass);
do {
//核心处理方法
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
//一见庐山真面目了
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
// recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass);
// process any @PropertySource annotations
//处理property资源文件的导入
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) {
processPropertySource(propertySource);
}
// process any @ComponentScan annotations
AnnotationAttributes componentScan = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ComponentScan.class);
if (componentScan != null) {
// the config class is annotated with @ComponentScan -> perform the scan immediately
if (!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// check the set of scanned definitions for any further config classes and parse recursively if necessary
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
if (ConfigurationClassUtils.checkConfigurationClassCandidate(holder.getBeanDefinition(), this.metadataReaderFactory)) {
//处理扫描出来的@configuration类
parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName());
}
}
}
}
// process any @Import annotations
//处理导入的configuration类
processImports(configClass, sourceClass, getImports(sourceClass), true);
// process any @ImportResource annotations
//处理xml配置文件
if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
String[] resources = importResource.getStringArray("value");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// process individual @Bean methods
//处理bean
Set<MethodMetadata> beanMethods = sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName());
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// process superclass, if any
//获取父类,asm不能获取所有的,所以标准的StandardAnnotationMetadata也没有处理父类的方法
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// superclass found, return its annotation metadata and recurse
try {
return sourceClass.getSuperClass();
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(ex);
}
}
}
// no superclass, processing is complete
return null;
}
处理加载资源文件,加载beandefinition等功能外, ConfigurationClassPostProcessor 也 会将 对应的Configuration Beandefinition 进行增强。
ContextAnnotationAutowireCandidateResolver
处理@Lazy
工具类
AnnotationMetadata: 类注解元数据信息类. 实现有StandardAnnotationMetadata(使用class反射)和 使用asm读取class文件,直接解析的AnnotationMetadataReadingVisitor