Spring源码解析01

192 阅读3分钟

常见的一些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方法,