Spring源码解读之获取Bean

上一篇文章我们搭建了源码环境,并使用了Spring方法获取了Bean,我们下边来回顾下代码

package com.pv3;

import com.pv3.config.AnnotationConfig;
import com.pv3.utils.TestUtil;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
  public static void main(String[] args) {
	  //启动Spring
	  AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AnnotationConfig.class);
	  TestUtil bean = annotationConfigApplicationContext.getBean(TestUtil.class);
	  bean.hello();

  }
}

Spring初始化做了什么?

AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AnnotationConfig.class);

1、AnnotationConfigApplicationContext实例化做了如下事情:

​ 1、执行AnnotationConfigApplicationContext父类org.springframework.context.support.GenericApplicationContext#GenericApplicationContext()的构造函数

	public GenericApplicationContext() {
    // 暂且实例化下啥也没有干
		this.beanFactory = new DefaultListableBeanFactory();
	}

​ 2、执行GenericApplicationContext父类构造函数org.springframework.context.support.AbstractApplicationContext#AbstractApplicationContext()

	public AbstractApplicationContext() {
		this.resourcePatternResolver = getResourcePatternResolver();
	}

​ 3、执行GenericApplicationContext父类org.springframework.context.support.AbstractApplicationContext#getResourcePatternResolver

	protected ResourcePatternResolver getResourcePatternResolver() {
    // 这里啥也没有返回默认Null
		return new PathMatchingResourcePatternResolver(this);
	}

​ 4、执行AbstractApplicationContext父类org.springframework.core.io.DefaultResourceLoader#DefaultResourceLoader()构造函数

	public DefaultResourceLoader() {
    // 这个是一个线程安全的加载类,AppClassLoader应用类加载器,又称为系统类加载器,负责在JVM启动时,加载来自在命令java中的classpath或者java.class.path系统属性或者CLASSPATH操作系统属性所指定的JAR类包和类路径.实际使用的是System.getSecurityManager();获取的默认加载器。
		this.classLoader = ClassUtils.getDefaultClassLoader();
	}

​ 5、初始化了一堆变量,有几个原子类,和日志类,还有定义了几个类名加变量。

​ 6、通过类加载器加载JSR-*330*加载失败就返回一个空,但是这个是Spring一类必须的!

​ 7、执行org.springframework.context.annotation.AnnotatedBeanDefinitionReader构造函数

	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);
	}

备注: 1、registry是之前调用构造函数传进来的org.springframework.context.annotation.AnnotationConfigApplicationContext

2、environmentgetOrCreateEnvironment()返回的StandardEnvironment实例

3、初始化了AnnotationConfigApplicationContext的工厂DefaultListableBeanFactory

4、使用了前边说的默认资源加载器。

5、AnnotationConfigApplicationContext资源加载。

6、加载检查一堆注解!检查类解析器的bean,AutoWired注解解析器,注册解析@Required 注解的处理器, 解析JSR250规范的注解,检查是否支持jpa,@EventListener的注解。

new ClassPathBeanDefinitionScanner(this); 创建类路径下的bean定义扫描器

自此Bean注册获取也就讲完!AnnotationConfigApplicationContext就是干这个用的!