前言
在上一篇文章中,我们了解了IOC(基于注解)的构造器的初始化过程Spring源码(1)IOC 的初始化流程(构造器篇,基于注解)
这一篇我们开始register(componentClasses)方法的讲解
我们先回顾一下程序入口
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//调用无参构造器
//在本类创建 AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
this();
//读取componentClasses为BeanDefinition,并保存到BeanDefinitionMap中
register(componentClasses);
refresh();
}
这里没什么好说的,我们直接进入register方法
//AnnotationConfigApplicationContext
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
//AnnotatedBeanDefinitionReader
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
这里使用AnnotatedBeanDefinitionReader进行注册,代码很简单我们直接来到doRegisterBean(这里说一点,其实spring真正进行操作的方法都是以do开头的,没do开头一般只做一些准备操作)方法进行讲解
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//将beanClass解析为BeanDefinition对象
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//conditionEvaluator是在AnotatedBeanDefinitionReader类初始化的时候初始化的,
//ConditionEvaluator这个类主要用于完成条件注解@Conditional的解析和判断。
//@Conditional 是Spring 4框架的新特性。此注解使得只有在特定条件满足时才启用一些配置。
//ConditionEvaluator的shouldSkip就是用于判断@Conditional下的而配置是否被启用。
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//supplier a callback for creating an instance of the bean
//这里设置的supplier,会在doCreateBean 的时候使用它来创建实例
abd.setInstanceSupplier(supplier);
//获取作用域
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//设置作用域
abd.setScope(scopeMetadata.getScopeName());
//获取beanName,如果传入的beanName为空,则调用beanName生成策略
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//注解处理
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//下面这一段代码是针对 @Qualifier注解的,一般情况下,
// @Autowired是根据类型进行自动装配的。
// 如果当Spring上下文中存在不止一个该类型的bean时,就会抛出BeanCreationException异常。
// @Qualifier可以配置自动依赖注入装配的限定条件,
// @Qualifier 可以直接指定注入 Bean 的名称,简单来说,
// @Autowired 和 @Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了。
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));
}
}
}
//可以BeanDefinitionCustomizer的回调去修改BeanDefinition的信息
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
//这里面定义了beanDefinition的名称和beanDefinition实例还有别名
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//在为创建该类的时候使用什么代理模式去创建,主要应用在为singleton注入其他作用域的对象的时候
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//将BeanDefinition注册到BeanDefinitionMap中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
这里主要做了一下几步
- 将beanClass解析为BeanDefinition对象
- 生成BeanDefinition name
- 将BeanDefinition name 和BeanDefinition 以key value的方式保存到BeanDefinitionMap中
下面我们将会对doRegisterBean中的一些比较重要的方法进行讲解
- ScopeMetadata scopeMetadata =
this.scopeMetadataResolver.resolveScopeMetadata(abd);
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
//只有AnnotatedBeanDefinition的子类才支持解析注解元数据,不是的话周就直接返回默认ScopeMetadata
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
annDef.getMetadata(), this.scopeAnnotationType);
//如果不为空的话就获取并设置注解相关信息
if (attributes != null) {
//获取scope注解的value值并保存
metadata.setScopeName(attributes.getString("value"));
//设置proxyMode
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = this.defaultProxyMode;
}
metadata.setScopedProxyMode(proxyMode);
}
}
return metadata;
}
//ScopedProxyMode 是一个枚举类
public enum ScopedProxyMode {
//默认为INTERFACES
DEFAULT,
//关闭ScopedProxy
NO,
//CGlib
INTERFACES,
//JDK动态代理
TARGET_CLASS
}
我相信你们对于ScopedProxyMode肯定有很多疑问,我们这里先简单地理解(后面我们会着重的讲)为,当我初始化时向scope 为singleton(我们把它称为singletonBean)的bean中注入一个socpe session(我们把它称为sessionBean)的bean,此时sessionBean时无法创建的,所以此时就需要给它创建一个代理对象。
- String beanName = (name != null ? name :
this.beanNameGenerator.generateBeanName(abd, this.registry));
//如果入参的name为null的话这调用方法generateBeanName生成beanName
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
if (definition instanceof AnnotatedBeanDefinition) {
//获去@Component的value值
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
// Explicit bean name found.
return beanName;
}
}
// 使用默认策略生成beanName
return buildDefaultBeanName(definition, registry);
}
protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
//获取元数据
AnnotationMetadata amd = annotatedDef.getMetadata();
//获取注解类型
Set<String> types = amd.getAnnotationTypes();
String beanName = null;
for (String type : types) {
//保存了注解里的所有数据
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
if (attributes != null) {
//保存到缓存,这里保存了type为key,set为value,set里面保存在type里多有注解信息
Set<String> metaTypes = this.metaAnnotationTypesCache.computeIfAbsent(type, key -> {
Set<String> result = amd.getMetaAnnotationTypes(key);
return (result.isEmpty() ? Collections.emptySet() : result);
});
//判断是否是component或者包含component
if (isStereotypeWithNameValue(type, metaTypes, attributes)) {
//获取value的值
Object value = attributes.get("value");
if (value instanceof String) {
String strVal = (String) value;
if (StringUtils.hasLength(strVal)) {
//不明白这里判空的意义在哪里
if (beanName != null && !strVal.equals(beanName)) {
throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
"component names: '" + beanName + "' versus '" + strVal + "'");
}
beanName = strVal;
}
}
}
}
}
return beanName;
}
protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
return buildDefaultBeanName(definition);
}
protected String buildDefaultBeanName(BeanDefinition definition) {
//获取className
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
//获取简单类名,意思就是不包含包名
String shortClassName = ClassUtils.getShortName(beanClassName);
//首字母小写
return Introspector.decapitalize(shortClassName);
}
这里主要做了一下操作:
判断是否有Component注解,有的话,获取value的值,否则,使用默认beanName生成策略,也就是首字母小写的类名
- AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
processCommonDefinitionAnnotations(abd, abd.getMetadata());
}
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
//获取并设置bean上注解(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"));
}
}
//获取并设置bean上注解(Primary)的信息
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
//获取并设置bean上注解(DependsOn)的信息
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
//获取并设置bean上注解(Role)的信息
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
abd.setRole(role.getNumber("value").intValue());
}
//获取并设置bean上注解(Description)的信息
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
abd.setDescription(description.getString("value"));
}
}
- definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata,
definitionHolder, this.registry);
static BeanDefinitionHolder applyScopedProxyMode(
ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
//如果为NO,则不做处理,直接返回
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
return definition;
}
//校验scopedProxyMode是否为ScopedProxyMode.TARGET_CLASS,(TARGET_CLASS:CGLIB)
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
//创建代理BeanDefintion,并返回
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
public static BeanDefinitionHolder createScopedProxy(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) {
return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass);
}
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
BeanDefinitionRegistry registry, boolean proxyTargetClass) {
//获取原本的beanDefinition Name,beanDefinition实例,targetBeanName = "scopedTarget."+originalBeanName
String originalBeanName = definition.getBeanName();
BeanDefinition targetDefinition = definition.getBeanDefinition();
String targetBeanName = getTargetBeanName(originalBeanName);
//创建一个代理beanDefinition
RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
//设置代理的BeanDefinitionHolder
proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
//设置代理的BeanDefinition
proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
//资源
proxyDefinition.setSource(definition.getSource());
//角色
proxyDefinition.setRole(targetDefinition.getRole());
//配置属性值,后面再填充属性的时候你就会明白
proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
//ScopedProxyMode 是否为TARGET_CLASS
if (proxyTargetClass) {
targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// ScopedProxyFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.
}
else {
proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
}
// Copy autowire settings from original bean definition.
//设置是否支持候选bean,后面填充属性会讲解
proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
//设置Primary
proxyDefinition.setPrimary(targetDefinition.isPrimary());
if (targetDefinition instanceof AbstractBeanDefinition) {
proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
}
// The target bean should be ignored in favor of the scoped proxy.
//设置被代理的Bean
targetDefinition.setAutowireCandidate(false);
targetDefinition.setPrimary(false);
// 将被代理的bean注册到BeanDefinitionMap中
registry.registerBeanDefinition(targetBeanName, targetDefinition);
// 返回代理的BeanDefinitionHolder
return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
}
到这里,register方法的基本流程就已经讲完了
我们一起来看看做了什么事情
- 将beanClass解析为BeanDefinition对象
- 判断是否有condition注解,是否满足condition的条件
- 生成BeanDefinition name
- 对Lazy,Primary,DependOn等注解的设置
- 可以BeanDefinitionCustomizer对BeanDefiniton进行回调处理
- 处理并返回BeanDefinitionHolder
- 将BeanDefinition name 和BeanDefinition 以key
value的方式保存到BeanDefinitionMap中