spring5源码阅读(一)new AnnotationConfigApplicationContext(Appconfig.class)入口

文章目录

    • 1.spring入口
      • 1.1 demo
      • 1.2 入口说明
    • 2.new AnnotationConfigApplicationContext
      • 2.1 this()
        • 2.1.1 方法作用
        • 2.1.2 如何作用的
      • 2.2 register(annotatedClasses)
        • 2.2.1 方法作用
        • 2.2.1 如何作用的
      • 2.3 refresh()

Spring,让我们java开发变得越来越简单,越来越高效,一系列组件功能非常强大。其核心的 IOC和AOP对于大家,可能熟悉而又陌生。因为大家都知道于这俩东西,也知道这俩东西的作用,但是对于具体的实现原理,有些童鞋可能不是很清楚。一直以来我也只是会用,今天,让我们一起阅读spring的源码,看看spring究竟是如何实现的。
上面正式开场白就扯这么多吧,源码咱们直接开撸。

本文基于spring 5.0.x版本分析

1.spring入口

spring源码非常繁多,功能模块也多;需要找到一个合适的入口进行阅读。
spring配置可以通过XML或者java配置类或者注解几种方式,但由于目前spring流行通过配置类+注解方式,因此我们从这样一个demo开始。

1.1 demo

public class MyMain {
	public static void main(String[] args) {
		//创建并初始化spring容器
		AnnotationConfigApplicationContext annotationConfigApplicationContext =
				new AnnotationConfigApplicationContext(Appconfig.class);
		//容器就是各种map实现的,getbean等同于map.get(key)
		CommonService commonService = annotationConfigApplicationContext.getBean(CommonService.class);
		commonService.query();
	}
}

//简单的配置类
@Configuration
@ComponentScan("com.test")
public class Appconfig {
}

//简单的service接口
public interface CommonService {
	void query();
}
@Component
public class CommonServiceImpl implements CommonService {
	@Override
	public void query() {
		System.out.println("query method");
	}
}

执行main方法,输出query method;

1.2 入口说明

上述demo很简单,
1.初始化容器,这里new了一个AnnotationConfigApplicationContext容器;
2.从容器中get到service类;
3.执行service类中的方法;

第一步,我们采用的是配置类+注解的方式,如果使用传统的xml配置,应该是这样的:
ApplicationContext apc = new ClassPathXmlApplicationContext(“xxx.xml”);

这里还有一点要说明下,在实际我们项目中,除非使用springboot(关于这种方式,确实有main方法,具体详情可参考我的另外一篇文章《springboot启动流程+自动配置原理》),我们好像并没有这种main方法去启动spring;

这个实际上是通过其他方式启动的,比如我们通常是web服务,都是有web.xml配置文件的,随便打开一个项目的web.xml你就会发现有如下必须配置:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

这是一个监听器,实现了servlet中的接口,也就是说,在web容器启动的时候,比如tomcat启动的时候,就会触发这个ContextLoaderListener#contextInitialized方法执行,这就是web项目启动spring框架的入口,最终都会初始化一种spring容器,效果与AnnotationConfigApplicationContext容器类似,都只是ApplicationContext接口的不同实现。

2.new AnnotationConfigApplicationContext

我们还是继续讲述通过配置类+注解使用spring的方式。
通过上述demo,我们发现,通过new AnnotationConfigApplicationContext一行代码,spring就初始化好了容器。
我们先看下AnnotationConfigApplicationContext的类图:
spring5源码阅读(一)new AnnotationConfigApplicationContext(Appconfig.class)入口_第1张图片
注意其中两个比较关键的接口ApplicationContext和BeanFactory;
其中,
BeanFactory是最底层接口,作用就是提供了访问bean容器的各种基础方法;
ApplicationContext是BeanFactory扩展,是最核心的接口,像本节讲的AnnotationConfigApplicationContext以及基于xml的ClassPathXmlApplicationContext,都只是它的不同实现。
类图比较复杂,先放在这里,这个需要我们时不时的回顾;

再次回到 new AnnotationConfigApplicationContext(Appconfig.class),进入这个构造方法:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//1.会首先调用父类GenericApplicationContext中的构造方法,初始化工厂bean为new DefaultListableBeanFactory()
		//2.调用自己的构造方法,初始化了一个读取器:AnnotatedBeanDefinitionReader reader;一个扫描器:ClassPathBeanDefinitionScanner scanner
		//3.在reader的初始化构造方法中,还注册了6个post processors
		this();
		//注册bean,注册就是把bean都放在某个地方,一个并发map中,Map beanDefinitionMap
		//这调用了AnnotatedBeanDefinitionReader reader的注册方法
		//只注册了6个post process 类
		register(annotatedClasses);
		//实现的bean的初始化;
		//自定义的bean也在这里注册并初始化
		refresh();
	}

此构造方法只执行了3个方法,整体实现的功能就是容器的初始化,包括bean的定义初始化,都在这3步完成;
其中,

  • 前两步完成了bean的定义和注册;就是先获取bean的定义描述,比如bean是不是单例,是不是懒加载,bean上的注解信息等等,这些都属于bean的定义,统统封装在一个BeanDefinition类型的bean中;注册,这个就更简单了,就是把BeanDefinition存到某个map中,key就是bean的名字beanName。
  • 第3步完成了bean的初始化,就是bean的实例化,外加bean的注入,如果有配置代理,生成代理类

下面我们逐个方法说明。

2.1 this()

2.1.1 方法作用

这里先直接说明this方法中干了什么,然后在讲怎么干的。
2个作用:

  • 指定默认的bean factory
  • 注册了6个post processors bean

2.1.2 如何作用的

下面说如何干的:
this是执行自己的构造方法,通过java语法我们知道,在执行自己的构造方法之前,会先执行父类中的构造方法,那我们先看父类的构造方法:

public GenericApplicationContext() {
	//默认的BeanFactory
	this.beanFactory = new DefaultListableBeanFactory();
}

内容不多,就是初始化了自己内部的beanFactory为DefaultListableBeanFactory,后边会用,这个我们先记住就好了。到这里,算是完成了第一个作用。

然后再看如何注册bean的定义的。先提前透漏下,所谓的注册,就是往一个map中存数据,这个map,在容器中(AnnotationConfigApplicationContext)维护。

继续,由于后边调用链路比较深,我们还是分步骤1234吧,不然太深了,容易迷路。

1.自己的this方法

public AnnotationConfigApplicationContext() {
	//AnnotatedBeanDefinitionReader的构造函数参数是BeanDefinitionRegistry接口类型
	//this实现了BeanDefinitionRegistry接口,所以可以作为参数传入
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

构造方法中初始化了:

  • 一个bean定义读取器:AnnotatedBeanDefinitionReader reader,就是提供了bean定义相关的操作,比如注册bean的定义。
  • 一个扫描器:ClassPathBeanDefinitionScanner scanner;
    其中scanner我们先不看了,不影响我们理解IOC和AOP。

2.new AnnotatedBeanDefinitionReader(this)
到这里,this()方法还没完,我们再继续深入,看下this中的这行代码:
this.reader = new AnnotatedBeanDefinitionReader(this);
在new一个 AnnotatedBeanDefinitionReader的时候,传入了this,也就是本节要讲的AnnotationConfigApplicationContext,点开看:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
	this(registry, getOrCreateEnvironment(registry));
}

其中入参是一个注册者BeanDefinitionRegistry,就是说所有注册动发生在这里边。这里传入的是容器AnnotationConfigApplicationContext,因为它实现了BeanDefinitionRegistry接口(回去看类图),所以可以作为入参。

上边这个方法是个皮包方法,没啥内容,继续进入:

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);
	//注册一些Processors
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

看最后一行,快找到注册bean postprocess的地方了,继续进入最后一行:

3.AnnotationConfigUtils#registerAnnotationConfigProcessors(this.registry)

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
	registerAnnotationConfigProcessors(registry, null);
}

又没啥内容,继续进入:
终于到了关键代码了: 注册6个post processors,就在这里:

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
		BeanDefinitionRegistry registry, @Nullable Object source) {

	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	if (beanFactory != null) {
		if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
			beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
		}
		if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
			beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
		}
	}
	//存放6个不同功能的post processor
	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
	//判断beanFactory的beanDefinitionMap中是否已经存在了ConfigurationClassPostProcessor Bean
	//开始都是不存在的,进入if内部
	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));
	}

	if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
	if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
	if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition();
		try {
			def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
					AnnotationConfigUtils.class.getClassLoader()));
		} catch (ClassNotFoundException ex) {
			throw new IllegalStateException(
					"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
		}
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
	}

	return beanDefs;
}

代码说明:
方法比较长,其实逻辑比较简单,不同的if判断,注册不同的post processer,所以我们就看一个if判断就行:

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));
}
  • 判断registry的beanDefinitionMap中是否已经存在了ConfigurationClassPostProcessor Bean,这个registry就是容器AnnotationConfigApplicationContext;判断是否包含,就是判断其中的map中是否有某个key(bean名字),如果没有就放到map中。
  • registerPostProcessor(),就是注册动作;

4.AnnotationConfigUtils#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);
}

看倒数第二行,registry.registerBeanDefinition(beanName, definition):

  • registry :就是容器AnnotationConfigApplicationContext;registerBeanDefinition()方法在其父类GenericApplicationContext中。
  • 参数 beanName:就是要注册bean的名字,如果没有特殊指定,就是类型小写;当然这里我们在说那6个post process,beanName都是有特殊指定的,可以看步骤3中的那些常量。
  • 参数 definition:bean的定义描述。

代码继续深入吧!

5.GenericApplicationContext#registerBeanDefinition

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {
	//DefaultListableBeanFactory
	this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}

这个beanFactory,就是我们在2.1.2节最开始说的父类构造方法初始化的默认beanFactory。
就剩这一行代码了,到最后了,我们进去看下:

6.DefaultListableBeanFactory#registerBeanDefinition
注意代码中的注释:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {

	Assert.hasText(beanName, "Bean name must not be empty");
	Assert.notNull(beanDefinition, "BeanDefinition must not be null");

	if (beanDefinition instanceof AbstractBeanDefinition) {
		try {
			((AbstractBeanDefinition) beanDefinition).validate();
		} catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
					"Validation of bean definition failed", ex);
		}
	}
	//注册BeanDefinition,就是将BeanDefinition放入一个map中,key是beanName
	//注册之前,先查下是否被注册过
	BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
	//如果已经存在,那么就检查是否允许覆盖,不允许直接跑异常,允许的话就记录一些日志,然后覆盖
	if (existingDefinition != null) {
		//默认允许覆盖
		if (!isAllowBeanDefinitionOverriding()) {
			//如果bean已经被注册了,并且不允许覆盖,那么抛出异常
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
					"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
							"': There is already [" + existingDefinition + "] bound.");
		} else if (existingDefinition.getRole() < beanDefinition.getRole()) {
			// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
			if (logger.isWarnEnabled()) {
				logger.warn("Overriding user-defined bean definition for bean '" + beanName +
						"' with a framework-generated bean definition: replacing [" +
						existingDefinition + "] with [" + beanDefinition + "]");
			}
		} else if (!beanDefinition.equals(existingDefinition)) {
			if (logger.isInfoEnabled()) {
				logger.info("Overriding bean definition for bean '" + beanName +
						"' with a different definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		} else {
			if (logger.isDebugEnabled()) {
				logger.debug("Overriding bean definition for bean '" + beanName +
						"' with an equivalent definition: replacing [" + existingDefinition +
						"] with [" + beanDefinition + "]");
			}
		}
		this.beanDefinitionMap.put(beanName, beanDefinition);
	} else {
		//检查bean的创建过程是否已经开始了
		//通过判断一个set集合是否为空,因为创建过的bean都会放到那个set中保存下
		if (hasBeanCreationStarted()) {
			// Cannot modify startup-time collection elements anymore (for stable iteration)
			synchronized (this.beanDefinitionMap) {
				this.beanDefinitionMap.put(beanName, beanDefinition);
				//下面4行是更新beanDefinitionNames的list
				List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
				updatedDefinitions.addAll(this.beanDefinitionNames);
				updatedDefinitions.add(beanName);
				this.beanDefinitionNames = updatedDefinitions;
				//manualSingletonNames人工注册的单例集合,也要更新
				if (this.manualSingletonNames.contains(beanName)) {
					Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
					updatedSingletons.remove(beanName);
					this.manualSingletonNames = updatedSingletons;
				}
			}
		} else {
			// Still in startup registration phase:仍然在启动注册阶段
			this.beanDefinitionMap.put(beanName, beanDefinition);
			this.beanDefinitionNames.add(beanName);
			this.manualSingletonNames.remove(beanName);
		}
		this.frozenBeanDefinitionNames = null;
	}

	if (existingDefinition != null || containsSingleton(beanName)) {
		resetBeanDefinition(beanName);
	}
}

方法说明:整体上逻辑比较简单,

  • 1.beanDefinitionMap:前边我一直说的注册动作,就是往某个map中的存东西,这个map就是方法中的beanDefinitionMap,是个ConcurrentHashMap;
  • 2.放到map之前,先查看map中是否已经存在了,如果已经存在,再判断是否允许覆盖;
  • 3.如果 map中不存在,那么就put进去。

到这里,AnnotationConfigApplicationContext构造方法中的3大步骤之一,this()方法就算看完了。

2.2 register(annotatedClasses)

现在继续看3大方法中的第二个,register(annotatedClasses);

2.2.1 方法作用

这个步骤方法叫register,顾名思义,就是进行一些注册相关的操作;这里再说到注册,我们应该很熟悉了,因为上面2.1.2节第4~6步骤,就是注册的核心方法;注册就是往某个map中存东西。
入参annotatedClasse就是我们demo中的AppConfig.class;因此,这一步的作用就是注册AppConfig的bean定义。

2.2.1 如何作用的

进入方法内部:

public void register(Class<?>... annotatedClasses) {
	Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
	this.reader.register(annotatedClasses);
}

调用的是读取器AnnotatedBeanDefinitionReader的注册方法,这个方法的入参支持一个数组,我们这里其实只传入了一个AppConfig.class,继续进入方法,如下:

public void register(Class<?>... annotatedClasses) {
	for (Class<?> annotatedClass : annotatedClasses) {
		registerBean(annotatedClass);
	}
}

因为入参数数组,所以要循环处理,继续进入registerBean如下:

public void registerBean(Class<?> annotatedClass) {
	doRegisterBean(annotatedClass, null, null, null);
}

是个皮包方法,继续进入doRegisterBean如下:

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
							@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
    //得到bean的描述信息,比如bean的注解,作用范围,是否懒加载,注入方式等
	AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
	//被条件注解@Conditional注释的bean跳过注册
	if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
		return;
	}

	abd.setInstanceSupplier(instanceSupplier);
	//解析bean的Scope,比如是否单例singleton还是其他
	ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
	abd.setScope(scopeMetadata.getScopeName());
	//生成bean name,默认就是类名小写
	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);
}

方法说明:这个方法整体同样分为3小步(只要是注册BeanDefinition,都是这3步),
1.根据class文件获取BeanDefinition,这里是其实现类 AnnotatedGenericBeanDefinition abd;
2.将BeanDefinition放到BeanDefinitionHolder中进一步封装;
3.最后一行,执行注册动作

所以我们继续进入最后一行:

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

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		//这里走的registerBeanDefinition#registerBeanDefinition
		//最终都要调用DefaultListableBeanFactory#registerBeanDefinition,放到bean factory的map中去
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// Register aliases for bean name, if any.
		//注册别名,就是放到一个专门存别名的map中
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

上述代码中,我们只看registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
熟悉吧,没错,就是2.1.2节中第4小步中讲的,忘记的再返上去看看,我们这里就不继续了。

2.3 refresh()

refresh()方法中,完成了bean的初始化操作,如果配置了aop,那代理类也是在这里产生。
由于此方法内容比较多,考虑的篇幅,咱们放到下一节中讲述《spring5源码阅读(二)refresh()方法》。

你可能感兴趣的:(spring)