spring

作者: 水流不流 | 来源:发表于2019-04-08 09:39 被阅读0次


    spring启动流程

    1:读取配置信息,将配置的文件信息转换Map<name,beanDefinition>
    2:根据上述的Map<name,beanDefinition>去创建bean,并完成依赖注入

    Spring MVC

    四大组件DispatcherServlet、HandlerMapping、HandlerAdapter以及ViewResolver
    启动流程:
    1.读取web.xml
    2.解析<context-param>里的键值对
    3.解析<listener>
    4.解析<filter>
    5.解析<servlet>
    如下图:

    Web应用部署tomcat初始化流程图

    dispatcherservlet执行流程:
    doService->doDispatch->getHandler(向HandlerMapping请求查找HandlerExecutionChain)->getHandlerAdapter->如果是get请求判断请求头是否有修改,没有修改直接返回->applyPreHandle(按顺序依次执行HandlerInterceptor的preHandle方法)->handle->applyPostHandle(逆序执行HandlerInterceptor的postHandle方法)->processDispatchResult(渲染视图填充Model)

    filter是java web的标准,在servlet之前,所以在拦截器之前,里面有一个doFilter方法,拦截前和拦截后都在这里处理,基于入栈出栈模式。

    bean实例化流程

    bean初始化顺序

    Constructor > @PostConstruct > InitializingBean > init-method

    循环依赖问题

    这个说到注入依赖的三种方式,1.构造器注入;2.set方法注解注入;3.属性注解注入
    那如果类A依赖了类B,类B又依赖了类A呢?
    如果是构造器注入方式,这个时候创建bean将会异常,启动会报BeanCurrentlyInCreationException异常,
    如果是后两种方法注入,bean其实已经通过构造方法创建,只是它的依赖还没注入完成,但这个时候是可以去先注入的,spring通过3级缓存的方式,解决了这种循环依赖,完全创建好的bean放一层,依赖没注入好的放一层,第三层放要被实例化的对象的对象工厂类。
    比如:A->B->C-A,首先发现A在一、二层缓存没有,就找到第三层,并创建了一个,然后填充A的时候发下需要B,这个时候类似之前A的过程,然后创建C,填充C的时候发现需要A,就开始从缓存中一层层的找,发现在第三级,然后删除第三级缓存,放入第二级,返回A, 这个时候C就创建好了,C可以放入第一级,同时清理二级和三级缓存的数据。然后B也好了,再然后A也好了。

    IOC扩展点

    beanfactorypostprocessor 和 beanpostprocessor,是ioc的两个扩展点
    BeanFactoryPostProcessor
    可以在spring容器加载了bean的定义文件之后,在bean实例化之前执行的,可以修改bean的定义和属性,可以配置多个,然后通过order来控制执行顺序。
    BeanPostProcessor
    是在bean初始化前后执行的

    基础组件

    BeanFactory
    产生一个新的实例,本质是一个工厂,管理bean

    FactoryBean
    本质是一个bean,用户可以通过实现该接口定制实例化Bean的逻辑。根据该Bean的Id从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身, 如果要获取FactoryBean对象,可以在id前面加一个&符号来获取。

    ApplicationContext
    扩展于BeanFactory,拥有更丰富的功能,例如:添加事件发布机制

    Resource
    bean配置文件,一般为xml文件。可以理解为保存bean信息的文件

    BeanDefinition
    定义了bean的基本信息,根据它来创造bean

    Spring boot starter

    1.Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含spring.factories文件的JAR包
    2.根据spring.factories配置加载AutoConfigure类
    3.根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context

    Spring boot启动流程

    简单的说:
    扫描spring.factories文件,初始化Spring容器并启动,在这基础上加入各种扩展点,这些扩展点包括:ApplicationContextInitializer、ApplicationListener以及各种BeanFactoryPostProcessor等等。

    启动点
    SpringApplicationapp =new SpringApplication(Application.class);
    Environment env =app.run(args).getEnvironment();

    在SpringApplication构造方法里做了几件事:
    1.设置sources
    2.初始化webEnvironment,用于判断是不是一个web程序
    3.初始化initializers,主要是去spring.factories文件中读取key为ApplicationContextInitializer的value,然后调用createSpringFactoriesInstances创建ApplicationContextInitializer实例。
    4.初始化listeners,类似初始化initializers,去spring.factories文件中读取key为ApplicationListener的
    5.设置mainApplicationClass,通过获取当前调用栈,找到入口方法main所在的类,并将其复制给SpringApplication对象的成员变量mainApplicationClass

    SpringApplication对象的run方法:
    1.StopWatch记录程序的运行时间
    2.configureHeadlessProperty,设置系统属性java.awt.headless,默认true
    3.SpringApplicationRunListeners,spring.factories文件中读取该类型,实际上就是在SpringApplication对象的run方法执行的不同阶段,发布相应的事件给对应的监听器。
    4.创建并刷新ApplicationContext,加载使用注解的bean定义
    BeanFactoryPostProcessor

    父类,子类的类初始化,对象初始化的执行顺序

    执行顺序为:父类静态块儿>子类静态块儿>父类块儿>父类构造>子类块儿>子类构造

    Servlet的生命周期

    通过调用 init () 方法进行初始化。
    调用 service() 方法来处理客户端的请求。
    通过调用 destroy() 方法终止(结束)。

    相关文章

      网友评论

          本文标题:spring

          本文链接:https://www.haomeiwen.com/subject/xlcriqtx.html