上一章总结到,AnnotationConfigApplicationContext提供两种方式注册bean,一是注册指定的bean,二是扫描指定的包。本章主要描述前者的过程。
注册指定的bean
AnnotatedBeanDefinitionReader.register()向容器注册指定bean。该方法完成整个过程的调用,其总结步骤如下
- 解析元数据信息,如作用域
- 对bean定义的通用注解处理
- 对qualifiers数据处理
- 根据作用域创建代理对象
- 注册BeanDefinition
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 
 | public void register(Class<?>... annotatedClasses) {for (Class<?> annotatedClass : annotatedClasses) {
 registerBean(annotatedClass);
 }
 }
 public void registerBean(Class<?> annotatedClass) {
 doRegisterBean(annotatedClass, null, null, null);
 }
 
 <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
 @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
 
 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
 return;
 }
 
 abd.setInstanceSupplier(instanceSupplier);
 
 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));
 }
 }
 }
 for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
 customizer.customize(abd);
 }
 
 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
 
 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
 
 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
 }
 
 | 
解析元数据信息
该过程由AnnotationScopeMetadataResolver.resolveScopeMetadata()实现,主要用于解析bean是原生类型(prototype)还是单例类型(singleton)。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {ScopeMetadata metadata = new ScopeMetadata();
 if (definition instanceof AnnotatedBeanDefinition) {
 AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
 
 
 AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
 annDef.getMetadata(), this.scopeAnnotationType);
 if (attributes != null) {
 
 metadata.setScopeName(attributes.getString("value"));
 ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
 if (proxyMode == ScopedProxyMode.DEFAULT) {
 proxyMode = this.defaultProxyMode;
 }
 metadata.setScopedProxyMode(proxyMode);
 }
 }
 return metadata;
 }
 
 | 
处理通用注解
这里为啥叫通用注解,我其实觉得不太合适,我就是英文直译过来的。因为在我看来通用注解不应该只包含@Lazy、@Primary、@DependsOn。或者从某个角度来说,所有注解都应该通用。不过好像除了通用能简单描述一下,好像也没有其他更合适的词了。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 
 | public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {processCommonDefinitionAnnotations(abd, abd.getMetadata());
 }
 
 static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
 
 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"));
 }
 }
 
 
 if (metadata.isAnnotated(Primary.class.getName())) {
 abd.setPrimary(true);
 }
 
 
 AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
 if (dependsOn != null) {
 abd.setDependsOn(dependsOn.getStringArray("value"));
 }
 
 if (abd instanceof AbstractBeanDefinition) {
 AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
 AnnotationAttributes role = attributesFor(metadata, Role.class);
 if (role != null) {
 absBd.setRole(role.getNumber("value").intValue());
 }
 AnnotationAttributes description = attributesFor(metadata, Description.class);
 if (description != null) {
 absBd.setDescription(description.getString("value"));
 }
 }
 }
 
 | 
根据作用域创建代理对象
这个方法存在的意义是为了区分使用jdk代理还是cglib代理,这里主要为引入AOP埋下伏笔,主要还是在AOP中使用。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | static BeanDefinitionHolder applyScopedProxyMode(ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
 
 
 ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
 
 if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
 return definition;
 }
 
 boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
 
 return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
 }
 
 | 
注册BeanDefinition
向IOC中注册BeanDefinition跟XML一样,都调用的是BeanDefinitionReaderUtils.registerBeanDefinition()。spring源码之IOC - xml - 注册BeanDefinition
总结
整体来说,注解配置bean比XML要简单,在spring内部实现也要简单。没有复杂的xml解析过程,对应的Class属性值、id、name,都能直接获取的到,然后将其保存在BeanDefinition中,并注册IOC就完成了容器启动。