Spring相信每个人在开发的时候都用过,正因为他的灵活性与扩展性而被人们更广泛的使用,只需要一个注解就能搞定一切,下面让我们来一起看看他的源码并分析一下他是如何进行内部底层运作的吧!
通过一张图我们来大致了解一下Spring的流程
本文采用的是Spring版本进行讲解,并搭配主流加载配置类的方式进行解析:
AnnotationConfigApplicationContext annotationConfigApplicationContext= new AnnotationConfigApplicationContext(Appconfig.class);
上面的一串代码便是源码的入口,通过上述的AnnotationConfigApplicationContext进行切入讲解,首先通过这个对象他们先跑到这里:
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
让我们一个一个来分析他的方法,首先:
***this()***:这里面他会调用无参构造函数,首先会调用父类的GenericApplicationContext的无参构造函数,初始化DefaultListableBeanFactory并把它赋值给beanFactory
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
此时我们便分析完了他的父类了,之后再分析其中无参构造函数的读取器的作用,点开读取器之后我们会发现下面的代码:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
其中上面几行就是对参数的判断与初始化对象,让我们把目光移动到最后一行:
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
点进去之后会看到这样一段代码
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
1.里面主要就是判断容器中是否已经存在了ConfigurationClassPostProcessor Bean
2.如果不存在就通过RootBeanDefinition的构造方法获得ConfigurationClassPostProcessor的BeanDefinition
3.执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,当然这里注册其他Bean也是相同的流程。
BeanDefinition是什么,顾名思义,它是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是否懒加载,是否Primary等等,这个BeanDefinition也相当重要。
registerPostProcessor方法:
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
首先设置了一个Role,ROLE_INFRASTRUCTURE代表着是Spring内部,并非用户自定义的,然后又调用了registerBeanDefinition方法来注册他的BeanName和他的信息。这里仅仅是注册,可以简单的理解为把一些原料放入工厂,工厂还没有真正的生产。
上面已经介绍过,这里会一连串注册好几个Bean,在这其中最重要的一个Bean(没有之一)就是BeanDefinitionRegistryPostProcessor Bean。
ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口,BeanDefinitionRegistryPostProcessor接口又扩展了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor是Spring的扩展点之一,ConfigurationClassPostProcessor是Spring极为重要的一个类,必须牢牢的记住上面所说的这个类和它的继承关系。
至此Reader我们就分析完了,由于常规使用方式是不会用到AnnotationConfigApplicationContext里面的scanner的,所以这里就不看scanner是如何被实例化的了。
把目光回到最开始,再分析第二行代码:
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
//可理解为用来描述Bean
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
//判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//解析bean的作用域,如果没有设置的话,默认为单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
//获得beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析通用注解,填充到AnnotatedGenericBeanDefinition,注解例如Lazy,Role 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));
}
}
}
//把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
1.通过AnnotatedGenericBeanDefinition的构造方法,获得配置类的BeanDefinition,这里是不是似曾相似,在注册ConfigurationClassPostProcessor类的时候,也是通过构造方法去获得BeanDefinition的,只不过当时是通过RootBeanDefinition去获得,现在是通过AnnotatedGenericBeanDefinition去获得。
2.判断需不需要跳过注册,Spring中有一个@Condition注解,如果不满足条件,就会跳过这个类的注册。
3.然后是解析作用域,如果没有设置的话,默认为单例。
4.获得BeanName
5.解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description
6.限定符处理,不是特指@Qualifier注解,也有可能是Primary,或者是Lazy,或者是其他(理论上是任何注解,这里没有判断注解的有效性)
7.把AnnotatedGenericBeanDefinition数据结构和beanName封装到一个对象中(这个不是很重要,可以简单的理解为方便传参)
8.注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册:
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 获取beanName
String beanName = definitionHolder.getBeanName();
//注册bean registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Spring支持别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
到这里注册配置类也分析完毕了。大家可以看到其实到这里,Spring还没有进行扫描,只是实例化了一个工厂,注册了一些内置的Bean和我们传进去的配置类,真正的大头是在第三行代码:
refresh();
下一章我们详细讲解这个方法。