之 Spring处理注解的源码分析
管理注解bean定义的两个容器:
- AnnotationConfigApplicationContext
- AnnotationConfigWebApplicationContext
AnnotationConfigApplicationContext 的 Java doc 原语:
Standalone application context, accepting annotated classes as input.
... Alllows for registering classes one by one
using {@link #register(Class...)} as well as for classpath scanning using {@link #scan(String...)}.
这两个类是 直接依赖于注解 作为容器配置信息 的 IOC容器。
AnnotationConfigWebApplicationContext 是AnnotationConfigApplicationContext 的Web版本。
两者虽然实现方式略有差别,但处理注解的逻辑一样。
先扫描(scan(String...))类路径(classpath),然后一一注册(register(Class<?>...))。
简单点,以 AnnotationConfigApplicationContext 为例。
AnnotationConfigApplicationContext的源码:
package org.springframework.context.annotation;
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
// 读取器:读取注解的Bean,并注册到容器中。
private final AnnotatedBeanDefinitionReader reader;
// 扫描器:扫描类路径中注解的Bean,并注册到容器中。
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
// reader和scanner,功能类似,使用场景不同:annotatedClasses, basePakages.
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
super(beanFactory);
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/*********************************
* 1 区
***/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
/*********************************/
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(environment);
this.scanner.setEnvironment(environment);
}
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.reader.setBeanNameGenerator(beanNameGenerator);
this.scanner.setBeanNameGenerator(beanNameGenerator);
getBeanFactory().registerSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
}
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
this.reader.setScopeMetadataResolver(scopeMetadataResolver);
this.scanner.setScopeMetadataResolver(scopeMetadataResolver);
}
/***************************
* 2 区
***/
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.scanner.scan(basePackages);
}
/***************************/
@Override
protected void prepareRefresh() {
this.scanner.clearCache();
super.prepareRefresh();
}
}
请注意:
AnnotationCnofigApplicationContext 类的源码中的 “1 区”:
AnnotationConfigApplicationContext的基本功能在构造函数中完成。
实例化reader 和scanner;然后调用 register(Class<?>... annotatedClasses) 或 scan(String... basePackages) 方法;最后刷新。
而 register(Class<?>... annotatedClasses) 方法调用reader.register(Class<?>... annotatedClasses);
scan(String... basePackages) 方法调用scanner.scan(String... basePackages)。
AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner 功能类似,二者取其一。
AnnotationConfigApplicationContext 类的源码中的 “2 区”:
如下两个方法完成了Spring的扫描注册功能:
reader.register(Class<?>... annotatedClasses);
scanner.scan(String... basePackages);
reader.register(Class<?>... annotatedClasses) 的源码:
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
public void registerBean(Class<?> annotatedClass) {
registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null);
}
// 注解功能实现区
@SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
scanner.scan(String... basePackages) 源码:
public int scan(String... basePackages) {
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
doScan(basePackages); // 备注:重点关注此处
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
// 注解功能实现区
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
/**
* BeanDefinitionHoder: Holder for a BeanDefinition with name and aliases.
* BeanDefinition: A BeanDefinition describes a bean instance,
* which has property values, constructor argument values, and
* further information supplied by concrete implementations.
*/
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
for (String basePackage : basePackages) { // 多个包路径
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;
}
[待续]