1、spring启动流程
- web容器为web应用提供一个全局的上下文环境ServletContext,为IOC容器提供宿主环境。
- web.xml中有contextLoaderListener,在web容器启动时触发容器初始化事件(ApplicationContext可以理解为IOC容器,具体实现有多个,如XmlWebApplicationContext),加载所有的service、dao、数据库配置、事务等bean。
- 容器初始化之后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中。
- IOC容器初始化完毕后,开始初始化web.xml中配置的DispatcherServlet,mvc的IOC容器,加载controller的bean,并将上一步的ioc容器设置为自己的父容器。DispatcherServlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。(个人理解:mvc的IOC容器并不需要放入ServletContext,当接收到的请求为前端url请求时走的是mvc的IOC容器,当发布webservice服务时会走ioc容器)
2、spring bean加载过程
在IoC容器启动之后,并不会马上就实例化相应的bean,此时容器仅仅拥有所有对象的BeanDefinition(先通过扫描指定包路径下的spring注解,比如@Component、@Service、@Lazy @Sope等spring识别的注解或者是xml配置的属性(通过读取流,解析成Document,Document)然后spring会解析这些属性,将这些属性封装到BeanDefintaion这个接口的实现类中.)。只有当getBean()调用时才是有可能触发Bean实例化阶段的活动
实例化和初始化的区别:实例化是在jvm的堆中创建了这个对象实例,此时它只是一个空的对象,所有的属性为null。而初始化的过程就是讲对象依赖的一些属性进行赋值之后,调用某些方法来开启一些默认加载。比如spring中配置的数据库属性Bean,在初始化的时候就会将这些属性填充,比如driver、jdbcurl等,然后初始化连接。
bean的生命周期可以概括为9步:
- 实例化bean对象(通过构造方法或者工厂方法)
- 设置对象属性(setter等)(依赖注入)
- 如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。(和下面的一条均属于检查Aware接口)
- 如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身
- 将Bean实例传递给Bean的前置处理器的postProcessBeforeInitialization(Object bean, String beanname)方法
- 调用Bean的初始化方法(1.实现InitializingBean接口,继而实现afterPropertiesSet的方法 2.反射原理,配置文件使用init-method标签直接注入bean 3.@PostConstruct注解),三者的先后顺序:@PostConstruct > InitializingBean > init-method
- 将Bean实例传递给Bean的后置处理器的postProcessAfterInitialization(Object bean, String beanname)方法
- 使用Bean
- 容器关闭之前,调用Bean的销毁方法
补充。。
3、beanfactory和factorybean
4、spring解决循环依赖
https://blog.csdn.net/w_linux/article/details/80086950
https://www.cnblogs.com/wyq178/p/11415877.html
https://www.jianshu.com/p/8318afef215c