常见的一些IOC容器实现类
- AnnotationConfigApplicationContext 基于注解的IOC容器
- ClassPathXmlApplicationContext 基于XML文件的IOC容器
- AnnotationConfigServletWebServerApplicationContext 基于注解的webIOC容器
ApplicationContext和BeanFactory的区别
- BeanFactory是一个顶级接口,提供bean基本操作
- ApplicationContext是BeanFactory的子接口,同时实现了MessageSource,eventListner等接口
容器的初始化
以常用的AnnotationConfigApplicationContext举例
- 首先执行构造方法初始化2个扫描列,AnnotationBeanDefinitionReader来容器内部初始化扫描用的,ClassPathBeanDefinitionScanner 提供给外部使用的,根据外部传进的来的path进行bd的解析注册。
- AnnotaionBeanDefinitionReader使用的构造方法会注册6个BD,ConfigrutionClassPostProcessor(来进行configuration注解的解析和beanDefinition的注册),AutoWiredPostProcessor(属性注入的时候调用使用它来解析@Autowire),CommonAnnotaionPostProcessor(属性注入的时候调用它来解析@resource,@inject注解),RequiredAnnotaionPostProcessor(属性注入的时候来解析@Required注解),MessagePostProcessor和ListenerPostProcessor
- 执行refresh()刷新容器
- BeanFactoryPostProcess(),一般是给web容器使用的,在这里注入servletContextAware解析器
- invokeBeanFactorPostProcessor(),调用beanFactory的前置处理器,这个时候就需要调用我们之前注入的ConfigrationClassPostProcessor来完成我们的configration注解的解析和BeanDefinition的注入工作
- registeBeanPostProcessor(),来完成bean的前置处理器注册
- initMessageResouce(),初始化资源
- initListener(),初始化监听器
- onRefresh(),也是web容器才会实现的方法,tomcat就是在这里被创建的
对象实例化
- 执行构造器获取bean
- 判断是否需要提前暴露已用,如果需要的话把bean添加到SingleObjectFactory中
- 进入属性注入方法并调用 instanceAwareBeanPostProcessor的After(),根据返回值来判断是否要进行属性注入
- 跟进配置值的自动注入模式进行注入,调用直接创建的3个注解来解析@Autowired,@Resource,@Inject注解
- 执行实例化方法,判断对象是否实现了Awared接口,如果实现了就注入相应的值
- 调用beanPostProcessor Before()来解析@PostConstrutor注解
- 调用initiallizeBean AfterPropertySet(),调用init生命周期方法();
- 调用beanPostProcessor After() 来完成动态代理实现AOP
- 把最后的bean放入SignletonObjects中,清空二三级缓存
如何实现AOP
Spring的AOP实现是基于动态代理来实现的,@EnableAspectJ 会@import一个ImprtRegistar来导入AutoProxyCreator,这个类实现了smartInitializeBeanPostProcessor。所以该类是一个bean的后置处理器
SpringMVC的执行流程
dispatchServlet.doDispatch()
- 从handlerMapping中获取mappedHander
- 根据mappedHander获取对应的handerAdapter
- 执行拦截器对应的preHandle()
- 执行handerAdapter.handle()获取到modelAndView
- 执行拦截器的postHandle()
- 调用processResult(),找到对应的viewResolver进行渲染
- 执行拦截器的afterCompletion()
SpringBoot的启动流程
- SpringApplication.run()该方法是一个静态方法,最后会生成一个SpringApplication并调用run()返回
- SpringApplication的构造方法会根据当前的环境,设置webApplicationType
- run()方法 设置当前的环境
- 获取当前项目的bannerPrinter
- 根据当前环境创建IOC容器
- 调用容器的refresh()
- 调用AfterRefresh()
Springboot的自动注解流程
- @SpringBootApplication 注解内部包含一个@EnableAutoConfiguration注解
- @EnableConfiguration 会使用@Import注解导入AutoConfigrutionImportSeletor.class
- AutoConfigurationImportSelector 中seletImports()方法会调用getAutoConfigrutionEntry
- getAutoConfigrutionEntry()会扫描所以包下的META-INF/spring.factories文件找到所有的autoConfigrution
- context再invokeBeanFactoryPostPorcessor的时候会调用ConfigurationClassPostProcessor来解析import注解,但是并没有直接调用selectImports方法而是调用getAutoConfigrutionEntry获取到对应的configrution类
SpringBoot打包成war运行的原理
- 实现SpringBootServletInitializer接口并写config方法
- 由于SpringBootServletInitializer接口实现了webApplicationInitializer接口重新onStartUp()方法
- SpringServletContainerInitializer实现了Servlet3.0的一个规范,在servlet容器初始化的会调用所有的initializeer的onStartUp方法,