@Configuration
@ComponentScan("com.gwm.spring.pointcut")
public class MainConfig {
}
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
AopProxyOrderService bean = context.getBean(AopProxyOrderService.class);
}
而且把 MainConfig 配置类当做参数传入进去了,进入到 AnnotationConfigApplicationContext 类构造函数,源码如下:

可以清楚的看到分了三步大流程,下面就开始看看这三步大流程里面到底做了什么事吧?
首先来到就是 AnnotationConfigApplicationContext 类的构造函数,你第一眼看到的是 this() 调用本身,但是千万不要忽略这里也隐藏了一个 super() 调用。所以会进入到 AnnotationConfigApplicationContext 的父类 GenericApplicationContext,源码如下:

引入眼帘的就是直接 new 了一个 BeanFactory 对象,这就是我们常说的 Bean 工厂,全称叫做 DefaultListableBeanFactory 工厂,只要你获取到了这个 BeanFactory 对象,Spring 里面所有的东西你都能够获取到,所以这才叫真正的大工厂
然后回到 AnnotationConfigApplicationContext 构造函数中,继续看 this() 里面做了设么?源码如下:

直接在这里 new 了一个两个对象,一个是 reader、一个是 scanner,分别作用是什么么? reader 可以简单的理解为是 BeanDefinition 类定义的解析器,scanner 就是一个扫描器,这里主要关注 reader,继续进入 AnnotatedBeanDefinitionReader() 方法,如下:


发现有一行非常重要的代码,就是在这里会去把 Spring 中几个超级重要的内置类的 BeanDefinition 注册到BeanDefinitionMap 容器中,注意这里还是注册 BeanDefinition 还没实例化 bean (埋点1),Spring 就是靠最先的这几个类白手起家,然后发展成一个 Spring 大家族的,例举了几个重要的内置类如下:
/**
* Spring 容器启动就内置了 7 大功能类,全部加载都是通过这个 7 个人白手起家的
*
* // 全部类的扫描都是这个 ConfigurationClassPostProcessor 后置处理器处理的(@ComponentScan、@Import、实现特定接口等等)
* 1.org.springframework.context.annotation.internalConfigurationAnnotationProcessor = ConfigurationClassPostProcessor.clazz
*
* // @Autowired、@Value 属性注入就是这个后置处理器完成的
* 2.org.springframework.context.annotation.internalAutowiredAnnotationProcessor = AutowiredAnnotationBeanPostProcessor.clazz
*
* * CommonAnnotationBeanPostProcessor 类解析并处理的注解
* * static {
* * jsr250Present = ClassUtils.isPresent("javax.annotation.Resource", classLoader);
* * jpaPresent = ClassUtils.isPresent("javax.persistence.EntityManagerFactory", classLoader)
* * ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader);
* * }
* *
* // @Resource @Inject 就是靠这个类支持的
* 3.org.springframework.context.annotation.internalCommonAnnotationProcessor = CommonAnnotationBeanPostProcessor.clazz 主要是解析并处理 JSR-250 注解(@Resource)
*
* // JTA 注解支持类
* 4.org.springframework.context.annotation.internalPersistenceAnnotationProcessor = PersistenceAnnotationBeanPostProcessor.clazz
* 5.org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor = PersistenceAnnotationBeanPostProcessor.clazz
*
* / /@EventListener 事件监听注解支持
* 6.org.springframework.context.event.internalEventListenerProcessor = EventListenerMethodProcessor.clazz
* 7.org.springframework.context.event.internalEventListenerFactory = DefaultEventListenerFactory.clazz
*/
同样的 ClassPathBeanDefinitionScanner() 构造方法就啥事没干了,就是创建了一个 Scanner 对象完事,至此 this() 整个构造函数就看完了。

至此总结下 this() 构造函数中就是帮我们注册好了 Spring 内置的几个核心类 BeanDefinition,后面肯定会调用 getBean() 去实例化这几个内置类的。
然后再回到 AnnotationConfigApplicationContext 类的 register(MainConfig.class) 方法,这个方法不过多阐述,就是注册了 MainConfig 主配置类的 BeanDefinition 类定义,啥事没干。源码如下:

可以说 Spring 中最轻松的就属这个方法了。
然后就要看到 Spring 最最核心方法 refresh(),Spring 所有的组件实例化过程都在这里面,现在就去看看这里面的源码:

refresh() 方法里面包含了7大核心步骤,分别对应处理不同的事情,简单介绍下七大步骤核心功能如下:
步骤一:1、获取最先说到的调用 super() 创建出来的 ConfigurableListableBeanFactory 工厂对象;2、在这里也会去解析 XML 配置并把 BeanDefinition 注册到 Spring 容器
步骤二:就是去实例化上面埋点1里面提到的内置的核心类,源码如下:

步骤三:主要是去实例化 BeanPostProcessor 后置处理器,源码如下:

步骤四:主要是去注册事件广播器,用来派发事件监听事件,相信这里应该不用多说了,大家都懂
步骤五:收集实现了 ApplicationListener 接口的监听器
步骤六:这里是核心实例化 bean 的过程,单独在下面讲
步骤七:发送 context 完成实例化 bean 的事件,需要监听的可以自己监听,比如:SpringMVC 的 initStrategies() 初始化过程就是监听了这个事件完成的
这里主要是讲实例化 bean 的过程,所以其他几个步骤就带过,主要看到实例化过程的源码如下:


下面这段源码需要再脑海中有一个概念,Spring 在创建过程中也是一个 for 循环去处理的,所以下面所有的流程都是一个单线程完成的,而且每次过来就只会处理一个 bean 创建。


然后进入到 doGetBean() 流程,源码如下:

如果在以下三个缓存中能够取到值,就立马返回该值,然后实例化 bean 就算完成了

但是第一次过来实例化的 bean 肯定不可能从这三个缓存中取到值的,所以会走 else 逻辑,源码如下:

现在分析都是按照单实例 bean 分析的,所以条件成立,执行 if 逻辑,然后开始调用 getSingleton() 方法,源码如下:


getSingleton() 方法又会先去看下一级缓存中是否有值,如果有直接返回,没有则要开始去实例化 bean,实例化 bean 之前还调用 beforeSingletonCreation(beanName) 方法做个标记,表示说我要开始去实例化这个 bean 了,其他如果有并发操作的线程不要过来了。
打完标记就要开始去实例化 bean 了,然后调用 getObject() 方法获取实例化的 bean,刚刚入口传进来的是个 Lambada 函数表达式,所以在执行 getObject() 方法的时候,就会回调到 createBean() 方法

然后看到 createBean() 源码如下:

在进入到 doCreateBean() 方法,源码如下:

createBeanInstance() 一看这个方法的名字就可以猜到就是这里 调用构造函数创建 bean 实例的,但是这里创建出来的 bean 里面的属性(比如使用 @Autowired、@Value、@Resource等注解修饰的属性)还没有填充值,只是创建好了对象,可以说是半成品 bean 吧。
既然创建好了 bean,是不是要去给它填充属性值了,但是在填充属性之前还要干一件非常重要的事情就是,把刚刚创建好的半成品 bean 放在三级缓存中保存起来,作用就是为了能够解决循环依赖的问题,这个有个印象就可以,毕竟现在这里不是专门讲循环依赖,而是只关注实例化 bean 的流程,如果想要了解循环依赖可以去看我另一篇专门讲循环依赖的文章。
将半成品 bean 保存到三级缓存的源码如下:

注意 addSingletonFactory() 方法第二个是一个 Lambada 函数式方法,方法体如下所示:

是一个 for 循环,在挨个执行后置处理器的功能,并且还会返回一个实例 bean (可能是一样的,可能不是一样的),注意这个方法什么时候被调用呢?就要看 singletonFactory 对象工厂什么时候调用 getObject() 方法,只要 singletonFactory 对象工厂调用 getObject() 方法,就会触发这个 Lambada 表达式的方法体逻。

将半成品 bean 保存到三级缓存之后,就要开始去调用 populateBean() 方法为这个属性进行赋值,属性赋值的时候如果引用类型的变量(比如 @Autowired 等修饰的变量) 会在此触发 getBean() 操作,如果不是,那么就直接通过反射注入值




至此属性赋值就算完成了,然后返回,返回到调用的地方,源码如下:

此时 singletonObject 变量是由返回值的,就是创建好的实例 bean,然后再返回之前,还会把这个 bean 放到 Spring 的一级缓存中,并且清空二三级缓存数据,源码如下:


至此整个 getBean() 流程结束(中间涉及的一些后置处理器干预这里没讲,是因为基本上只有在切面的时候后置处理器才会发挥很大的作用)。