Spring容器启动流程
目的
本篇文章意在简单说明Spring容器的启动流程,通过学习Spring的启动流程,可以很好的理解Spring中的核心功能,例如Autowired、ComponentScan、Scope等相关注解,并且了解AOP的执行过程。
扫描
Spring在启动的时候,会去加载配置类AppConfig是否有通过@ComponentScan注解指定扫描路径范围,并且扫描的是target目录下的.class文件,并且转化为BeanDefinition对象,最后添加到beanDefinitionMap中,同时如果是BeanPostProcessor接口的实现类会存放到bean的后置器list中,之后在初始化前和初始化后使用
实例化
实例化就是创建实例的bean,并不是目录下所有的.class文件都会实例化,只有非懒加载的单例Bean才会被实例化,如果一个类上添加了@Scope(“prototype”)或者@Lazy 注解时,那么Spring启动时是不会实例化该对象的,只有在使用该对象的时候才会实例化
1.实例化
表示从target目录下获取所有非懒加载的单例Bean,并且为了后续流程不在走同样的实例流程,每次实例一个,就放入一个ConcurrentHashMap<String, BeanDefinition>集合中存起来,key为bean的名称,value为bean的定义类,里面描述了这个bean的一些信息,如是否为单例,是否为懒加载,bean的实例类型等等信息
2.属性填充
补充BeanDefinition信息,并且此处涉及注入依赖的问题,如果OrderService通过注解@Autowired注入到UserService 中,是先通过ByType类型去匹配,在通过ByName去寻找
3.初始化前
遍历BeanPostProcessor接口实现类list,执行postProcessBeforeInitialization方法在初始化前做增强处理
4.Aware回调
实现BeanNameAware接口中的setBeanName方法,获取Spring实例bean对象的别名
5.初始化
实现InitializingBean接口的afterPropertiesSet方法,表示在一个bean对象实例完成时,校验一下是否创建成功,例如:Spring创建UserService时,不希望注入的属性对象orderService为空,否则抛异常
5.添加到单例池
如果实例的对象是单例,则添加到创建的单例池中,以便后面使用的时候不需要再次实例化以便,直接从单例池中获取(这里比源码中的要简单一些,便于理解)
6.初始化后
遍历BeanPostProcessor接口实现类list,执行postProcessAfterInitialization方法在初始后前做增强处理,springAop就是在这里实现的