Spring AnnotationConfigApplicationContext 源码分析(2) ---->register(annotatedClasses);

上一篇把this()都讲完了,这一篇讲register(annotatedClasses);

其实这个方法的作用就是把配置类(下面例子中的annotatedClasses)包装为beanDefinition,之后加入到beanFactory 的beanDefinitionMap中。

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
		register(annotatedClasses);
		refresh();
	}

register 方法执行如下

public void register(Class<?>... annotatedClasses) {
	Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
	//reader 为上一篇文章this()方法实例的beanDefinitionReader
	this.reader.register(annotatedClasses);
}
②、=============================
public void register(Class<?>... annotatedClasses) {
	for (Class<?> annotatedClass : annotatedClasses) {
		registerBean(annotatedClass);
	}
}
③、=============================
public void registerBean(Class<?> annotatedClass) {
	registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null);
}
④、=============================
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);
	//设置bean定义的scope为singleton(默认单例)
	abd.setScope(scopeMetadata.getScopeName());
	String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
	//设置通用的bean定义注解,包含@Lazy,@Primary,@DependsOn	,@Role,@Description
	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);
}

我们直接看第四个方法
registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>… qualifiers)。
这个方法只有annotatedClass 有值为标有 @Configuration注解的配置类。例子如下:

@Configuration
@ComponentScan(basePackages = "com.xxxx.xxxxx")
public class MainConfig {
    @Bean(initMethod = "init")
    public Compent compent() {
        return new Compent();
    }
}

AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
把该annotatedClass配置类加入到bean定义里面,第一篇说到beanDefinition 就类似于java的Class。

========AnnotatedGenericBeanDefinition.java===========
public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
	setBeanClass(beanClass);
	this.metadata = new StandardAnnotationMetadata(beanClass, true);
}
========StandardAnnotationMetadata.java============
public StandardAnnotationMetadata(Class<?> introspectedClass, boolean nestedAnnotationsAsMap) {
	super(introspectedClass);
	this.annotations = introspectedClass.getAnnotations();
	this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
}

shouldSkip()方法説明:用于判断当前类的注解里面有没有含有@Conditional 或@ConditionalOnBean、、、、等等@Conditional 的衍生接口,如果没有就直接跳过,有就判断当前类的@Conditional中的value执向的类的matchs方法是否匹配。

if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
	return;
}
===============ConditionEvaluator.java
public boolean shouldSkip(AnnotatedTypeMetadata metadata) {
	return shouldSkip(metadata, null);
}
public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) {
		if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
			return false;
		}

		if (phase == null) {
			if (metadata instanceof AnnotationMetadata &&
					ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
				return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
			}
			return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
		}

		List<Condition> conditions = new ArrayList<Condition>();
		for (String[] conditionClasses : getConditionClasses(metadata)) {
			for (String conditionClass : conditionClasses) {
				Condition condition = getCondition(conditionClass, this.context.getClassLoader());
				conditions.add(condition);
			}
		}

		AnnotationAwareOrderComparator.sort(conditions);

		for (Condition condition : conditions) {
			ConfigurationPhase requiredPhase = null;
			if (condition instanceof ConfigurationCondition) {
				requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
			}
			if (requiredPhase == null || requiredPhase == phase) {
				if (!condition.matches(this.context, metadata)) {
					return true;
				}
			}
		}

		return false;
	}

最后说说BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);方法,其实就是往beanFactory里面的beanDefinitionMap中put入当前的bean定义。

public static void registerBeanDefinition(
		BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
		throws BeanDefinitionStoreException {

	// Register bean definition under primary name.
	String beanName = definitionHolder.getBeanName();
	registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

	// Register aliases for bean name, if any.
	String[] aliases = definitionHolder.getAliases();
	if (aliases != null) {
		for (String alias : aliases) {
			registry.registerAlias(beanName, alias);
		}
	}
}
===================GenericApplicationContext.java=============================
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {

	this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}

上一篇:#补充: tdsql(noshard)  到 tdsql(noshard)


下一篇:如何导出存储过程、函数、包和触发器的定义语句?如何导出表和索引的创建语句?...