spring启动过程
1、spring启动过程
spring的启动是建筑在servlet容器之上的,所有web⼯程的初始位置就是l,它配置了servlet的上下⽂(context)和(Listener),
下⾯就来看看l⾥⾯的配置:
spring的上下⽂
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/l</param-value>
</context-param>
<listener>
<listener-class>
org.t.ContextLoaderListener
</listener-class>
</listener>
spring的启动其实就是IOC容器的启动过程,通过上述的第⼀段配置<context-param>是初始化上下⽂,然后通过后⼀段的的<listener>来加载配置⽂件,其中调⽤的spring包中的ContextLoaderListener这个上下⽂,ContextLoaderListener是⼀个实现了ServletContextListener接⼝的,他的⽗类是 ContextLoader,在启动项⽬时会触发contextInitialized上下⽂初始化⽅法。下⾯我们来看看这个⽅法:
public void contextInitialized(ServletContextEvent event) {
ServletContext());
}
可以看到,这⾥是调⽤了⽗类ContextLoader的ServletContext());⽅法,很显然,这是对ApplicationContext的初始化⽅法,也就是到这⾥正是进⼊了springIOC的初始化。
这个⽅法主要做了三件事:实例化bean的三种方式
创建WebApplicationContext:这个就是spring的IoC容器,实际的实现类是XmlWebApplicationContext
加载对应的spring配置⽂件中的Bean。
将WebApplicationContext放⼊ServletContext(Java Web的全局变量)中。
createWebApplicationContext(servletContext)⽅法即是完成创建WebApplicationContext⼯作。configureAndRefreshWebApplicationContext就是⽤来加载spring配置⽂件中的Bean实例的。
最后完成ApplicationContext创建之后就是将其放⼊ServletContext中,注意它存储的key值常量。
2、SpringMVC的启动过程
<servlet>
<servlet-name>service_dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/services/l</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
这段为启动初始化DispatcherServlet ,l中设置了Servlet的load-on-startup:表⽰启动容器时初始化该Servlet。
所以在这样⼀个web容器启动的时候会调⽤HttpServletBean的init⽅法,这个⽅法覆盖了GenericServlet中的init⽅法。
初始化Spring Web MVC使⽤的Web上下⽂,并且指定⽗容器为WebApplicationContext(ContextLoaderListener加载了的根上下⽂);初始化DispatcherServlet使⽤的策略,如HandlerMapping、HandlerAdapter等。
3、Spring获取Bean的流程
解析-加载。
可以看到⼀个 Bean 加载会经历这么⼏个阶段:
获取BeanName,对传⼊的 name 进⾏解析,转化为可以从 Map 中获取到 BeanDefinition 的 bean name。
合并Bean定义,对⽗类的定义进⾏合并和覆盖,如果⽗类还有⽗类,会进⾏递归合并,以获取完整的 Bean 定义信息。
实例化,使⽤构造或者⼯⼚⽅法创建 Bean 实例。
属性填充,寻并且注⼊依赖,依赖的 Bean 还会递归调⽤ getBean ⽅法获取。
初始化,调⽤⾃定义的初始化⽅法。
获取最终的Bean,如果是FactoryBean 需要调⽤ getObject ⽅法,如果需要类型转换调⽤ TypeConverter 进⾏转化。
初始化流程:
触发Aware
如果我们的 Bean 需要容器的⼀些资源该怎么办?⽐如需要获取到 BeanFactory、ApplicationContext 等等。
Spring 提供了 Aware 系列接⼝来解决这个问题。⽐如有这样的 Aware:
BeanFactoryAware,⽤来获取 BeanFactory。
ApplicationContextAware,⽤来获取 ApplicationContext。
ResourceLoaderAware,⽤来获取 ResourceLoaderAware。
ServletContextAware,⽤来获取 ServletContext。
Spring 在初始化阶段,如果判断 Bean 实现了这⼏个接⼝之⼀,就会往 Bean 中注⼊它关⼼的资源。
触发 BeanPostProcessor
在 Bean 的初始化前或者初始化后,我们如果需要进⾏⼀些增强操作怎么办?
这些增强操作⽐如打⽇志、做校验、属性修改、耗时检测等等。Spring 框架提供了 BeanPostProcessor 来达成这个⽬标。⽐如我们使⽤注解 @Autowire 来声明依赖,就是使⽤ AutowiredAnnotationBeanPostProcessor 来实现依赖的查询和注⼊的。
只要 Bean 实现了 BeanPostProcessor 接⼝,加载的时候会被 Spring ⾃动识别这些 Bean,⾃动注册,⾮常⽅便。
然后在 Bean 实例化前后,Spring 会去调⽤我们已经注册的 beanPostProcessors 把处理器都执⾏⼀遍。
触发⾃定义init
⾃定义初始化有两种⽅式可以选择:
实现 InitializingBean。提供了⼀个很好的机会,在属性设置完成后再加⼊⾃⼰的初始化逻辑。
定义 init ⽅法。⾃定义的初始化逻辑。
类型转换
在返回给调⽤者之前,还留有⼀个机会对 Bean 实例进⾏类型的转换。见 AbstractBeanFactory.doGetBean

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。