当你的才华还撑不起你的野心的时候,唯有静下心来学习。
<>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实现(可以通过查看类关系,
AnnotationConfigApplicationContext是BeanDefinitionRegistry的一种实现),最终会调用
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的信息,其中
ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、
CommonAnnotationBeanPostProcessor这三个后置处理器非常的重要,其中ConfigurationClassPostProcessor
这个后置处理器是重中之重,后续使用的时候会进行讲解,这是只是想beanFactory中进行设置,但并没有使用,方便在后续时候过程中不知道他是如何产生的。

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

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

技术
©2019-2020 Toolsou All rights reserved,
MyBatis 新增数据 成功 返回 自增主键ID值用C语言做很简单的飞机游戏苹果不送充填器耳机真为环保?可能还是为了赚钱吧一个名叫“讨火车”的小村子 终于把火车讨来了使用easyPOI导入Excel数据QT:清空指定文件夹内的所有文件及目录json反斜杠问题3种Python数据结构,13种创建方法,这个总结,超赞!访客手机抓取方法改主意!特斯拉开始向欧洲市场交付中国造Model 3