小白Spring源码解读 —— (一)

当你的才华还撑不起你的野心的时候,唯有静下心来学习。
1. 简介

       在研究spring源码之前,首先要确保自身有使用过spring框架开发过项目,有一定的基础知识,比如知道什么是beanFactory、Ioc、依赖注入等,并且简单知道原理最好。由于spring源码体系庞大,无法做到涉及到每一个方面细节,只能讲解他的核心功能,一个章节也无法全部概述,可能会分多个章节。在读spring源码的过程中,如果只是单纯的看并不会有太大的收获,还是需要自己手动调式源码。本章是基于注解方式(AnnotationConfigApplicationContext)进行解读的。编写测试用例来模拟spring加载流程,当了解了spring的工作流程在谈他的如何进行融会贯的。
       一定要自己对着源码读,切记在读源码的过程中,不要死扣细节,要使用面向对象的思想来解读,只需要知道这段代码为我们做了什么就可以了,如果想深入了解,可以自己点进去深入研究,要不然代码段太长,容易绕晕不容易读下去。
       以一个项目为例,看spring是如何进行工作的,结构如下,随便使用一个spring项目就可以,并没有太大影响:
在这里插入图片描述
       编写一个测试类,进行spring加载:

@ComponentScan("com.online.manager")
public class AppController {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppController.class);
        // TODO1 到这一步spring已经加载完成
        UserController userController = context.getBean(UserController.class);
    }
}

       当测试执行到context.getBean的时候,spring容器已经加载完成了,所有我们需要查看new AnnotationConfigApplicationContext底层做了什么。当点击进入到AnnotationConfigApplicationContext类中(ctrl + 鼠标)的时候,我们进入的是这个构造方法:

	public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        // this 是调用自身的无参构造方法, 点进行查看
        // 本章节只讲这个this做了什么,不要看他简单,其实很深
        this();
        // 下一次讲
        this.register(annotatedClasses);
        this.refresh();
    }

       可以看见第一行代码this();他调用的是自身的无参构造方法,由于java特性知道在调用自身的无参构造方法,会先调用父类的无参构造方法,所以我们先进入他的父类(GenericApplicationContext)中查看他的无参构造。

       GenericApplicationContext无参构造方法:

	// 父类的这个属性非常重要,他就是spring的工厂
	private final DefaultListableBeanFactory beanFactory;
	public GenericApplicationContext() {
        this.customClassLoader = false;
        this.refreshed = new AtomicBoolean();
        // 在父类构造方法中初始化工厂 (很重要)
        this.beanFactory = new DefaultListableBeanFactory();
    }

       在GenericApplicationContext的类中,可以看到他有一个非常重要的属性,就是我们常说的bean工厂beanFactory,想看他的属性自己点进去查看,查看他有哪些属性。他的构造方法为我们的bean工厂进行实例化了spring工厂(只是创建但并没有初始化)。这就是beanFactory的真身,如果想深入了解可以继续查找GenericApplicationContext的父类为我们做了什么工作,这里就不在概述了。

       基于继承关系,AnnotationConfigApplicationContext类持有了这个beanFactory的实例,很重要。父类的构造方法执行完了,接下来看自己的构造方法。(不要绕晕了)

        AnnotationConfigApplicationContext无参构造方法:

	public AnnotationConfigApplicationContext() {
		// 把自身的实例传递给他的构造方法,创建了一个注解bean定义读取器,用来把我们的配置类解析成BeanDefinition。很重要
        this.reader = new AnnotatedBeanDefinitionReader(this);
        // 创建一个bean定义扫描器,在外部手动调用的,使用scan方法进行扫描,不重要可调过
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

      AnnotationConfigApplicationContext的构造方法通过把自身实例(this)传过去调用AnnotatedBeanDefinitionReader的构造方法创建一个注解bean定义读取器,作用用来把我们的配置类解析成BeanDefinition放入到beanFactory的beanDefinitionMap属性中。

       为什么要报this传过去呢?可以思考一下?
       因为这个this是AnnotationConfigApplicationContext的实例,而因为他父类的关系,所以他自己持有了bean工厂的实例。因此可以通过过来的this获取到我们的beanFactory工厂。

       但是在AnnotatedBeanDefinitionReader(this)的这个构造方法里帮我们做了很多的事情,这里面代码非常的重要,主要是完成beanFactory工厂的首次初始化工作,往下看。

       AnnotatedBeanDefinitionReader(this)构造方法:

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }
	// 最终调用的构造方法
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        ..... 不太重要的代码省略, 主要完成初始化
        // 很重要 -- 完成`beanFactory`工厂的首次初始化工作
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

       可以看到上面的这个BeanDefinitionRegistry registry参数的实际上就是我们的AnnotationConfigApplicationContext实现(可以通过查看类关系,AnnotationConfigApplicationContextBeanDefinitionRegistry的一种实现),最终会调用registerAnnotationConfigProcessors这个方法。

       registerAnnotationConfigProcessors方法(很重要):

	public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
        registerAnnotationConfigProcessors(registry, (Object)null);
    }
	// 最终调用这个方法
    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
        // 在这个方法里,从registry里获取我们的bean工厂,细节可以自己点进去查看(ctrl + 点击方法)
        // 实现是 把registry强转为GenericApplicationContext,调用他的getDefaultListableBeanFactory获取工厂
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        // 在之前工厂就已经创建好了,肯定不为空
        // 下面代码就是bean工厂的初始化工作了,只需要知道为我们工厂填充了这些属性,为了之后使用这些功能
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            	// 添加了比较器用于排序,(处理Ordered接口、PriorityOrdered接口功能)
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }

            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            // 提供延迟加载的功能
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(8);
        RootBeanDefinition def;
        // 向工厂注册的7个后置处理器非常重要也是完成spring的核心功能
        if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
            def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 向beanDefinitionMap加入ConfigurationClassPostProcessor后置处理器
            // 他实现的是BeanDefinitionRegistryPostProcessor接口
            // 主要完成自定义类(@Configuration、@Componet、@Serveice、@Import注解)的扫描,把我们定义的类加入到spring容器中
            // 后面会在使用的时候会详细介绍
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
        }

        if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
            def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            // 向beanDefinitionMap加入AutowiredAnnotationBeanPostProcessor后置处理器
            // 他实现的是BeanFactoryPostProcessor接口, 处理@Autowired,完成bean的属性注入的工作
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
        }

        // 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);
			// 向beanDefinitionMap加入CommonAnnotationBeanPostProcessor后置处理器
            // 他实现的是BeanFactoryPostProcessor接口, 处理@Resource和JSR 250注解
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		//jpa功能
		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;
    }

       registerAnnotationConfigProcessors这个方法很重要,完成beanFactory的初始化工作,向beanDefinitionMap中注册了7个后置处理器的BeanDefinition的信息,其中ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor这三个后置处理器非常的重要,其中ConfigurationClassPostProcessor这个后置处理器是重中之重,后续使用的时候会进行讲解,这是只是想beanFactory中进行设置,但并没有使用,方便在后续时候过程中不知道他是如何产生的。

       到这里AnnotationConfigApplicationContext的无参构造方法里的new AnnotatedBeanDefinitionReader(this)这行代码就执行结束了。该执行new ClassPathBeanDefinitionScanner(this)这段代码了,其实这段代码的用处不是很大,主要是提供外部也就是程序员自己在外部使用的,不重要,感兴趣的话可以自己点进去查看。

       到这里AnnotationConfigApplicationContext的构造方法里的this()方法就执行结束了,其中有很多细节的地方没有讲述清楚,可以的话可以自己进行查看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章