你好,我是yes。
话不多少,发车!
说下 Spring Bean 的生命周期
在说具体的生命周期前,我们需要先知晓之所以 Bean 容易被添加一些属性,或者能在运行时被改造就是因为在生成 Bean 的时候,Spring对外暴露出很多扩展点。
基于这些点我们可以设置一些逻辑,Spring 会在 Bean 创建的某些阶段根据这些扩展点,基于此进行 Bean 的改造。
有了上面的认识,我们再来看 Spring Bean 的生命周期,我用一幅图先总结一下:
大致了解生命周期之后,我们再来看详细的操作,可以看到有好多扩展点可以搞事情:
注意细节,这幅图的颜色和上面那副有对应关系的。
我再用文字描述一下:
- 实例化Bean。
- 根据属性,注入需要的 Bean。
- 如果 Bean 实现了 BeanNameAware 等 aware 接口,则执行 aware 注入。
- 如果有 BeanPostProcessor,则执行BeanPostProcessor#postProcessBeforeInitialization 方法。
- 如果 Bean 是 InitializingBean,则执行 afterPropertiesSet 方法。
- 如果有 initMethod ,则执行。
- 如果有 BeanPostProcessor,执行BeanPostProcessor#postProcessAfterInitialization 方法。
- 使用 Bean。
- 如果 Bean 是 DisposableBean,则执行 destroy 方法。
- 如果有 destroy 方法,则执行。
说下对 Spring MVC 的理解?
Spring MVC 是基于 Servlet API 构建的,可以说核心就是 DispatcherServlet,即一个前端控制器。
还有几个重要的组件:处理器映射、控制器、视图解析器等。
由这几个组件让我们与 Servlet 解耦,不需要写一个个 Servlet ,基于 Spring 的管理就可以很好的实现 web 应用,简单,方便。
然后关于 MVC 的解释,我就不提了,什么 Model,View,Controller 啥的。
Spring MVC 具体的工作原理?
当一个请求过来的时候,由 DispatcherServlet 接待,它会根据处理器映射(HandlerMapping)找到对应的 HandlerExecutionChain(这里面包含了很多定义的 HandlerInterceptor,拦截器)。
然后通过 HandlerAdapter 适配器的适配(适配器模式了解一下)后,执行 handler,即通过 controller 的调用,返回 ModelAndView。
然后 DispatcherServlet 解析得到 ViewName,将其传给 ViewResoler 视图解析器,解析后获得 View 视图。
然后 DispatcherServlet 将 model 数据填充到 view ,得到最终的 Responose 返回给用户。
我们常用的视图有 jsp、freemaker、velocity 等。
SpringMVC 父子容器是什么知道吗?
官网上有幅图可以了解下:
可以看到,services 和 repositories 是属于父容器的,而 Controllers 等是属于子容器的。
那为什么会有父子之分?
其实 Spring 容器在启动的时候,不会有 SpringMVC 这个概念,只会扫描文件然后创建一个 context ,此时就是父容器。
然后发现是 web 服务需要生成 DispatcherServlet ,此时就会调用 DispatcherServlet#init,这个方法里面最会生成一个新的 context,并把之前的 context 置为自己的 Parent。
这样就有了父子之分,这样指责就更加清晰,子容器就负责 web 部分,父容器则是通用的一些 bean。
也正是有了父子之分,如果有些人没把 controller 扫包的配置写在 spring-servlet.xml ,而写到了 service.xml 里,那就会把 controller 添加到父容器里,这样子容器里面就找不到了,请求就 404 了。
当然,如果你把 services 和 repositories 添加到子容器是没影响的,不过没必要,分层还是比较好的方式。
对了,子容器可以用父容器的 Bean,父容器不能用子容器的 Bean。
你了解的 Spring 都用到哪些设计模式
工厂模式,从名字就看出来了 BeanFacotry。
模板方法,什么 JdbcTemplate、RestTemplate 。
代理模式,AOP 整的都是代理。
单例,这都不需要说了。
责任链模式,比如拦截器。
观察者模式,Spring里的监听器。
适配器模式...SpringMVC 提到的 handlerApdaper。
太多啦...
Spring 事务有几个隔离级别
从源码定义我们可以看到,一共有 5 种隔离级别,而 DEFAULT 就是使用数据库定义的隔离级别。
其他几种分别是:读未提交、读已提交、可重复读、序列化。
具体几个隔离级别的概念我就不介绍了,应该都很清楚。
不清楚的看我这篇 MySQL 的文章:mysql总结。
文章的后半段有写。
Spring 有哪几种事务传播行为?
从源码来看,一共有 7 种事务传播行为:
- PROPAGATION_REQUIRED(默认) 如果当前存在事务,则用当前事务,如果没有事务则新起一个事务。
- PROPAGATION_SUPPORTS 支持当前事务,如果不存在,则以非事务方式执行。
- PROPAGATION_MANDATORY 支持当前事务,如果不存在,则抛出异常。
- PROPAGATION_REQUIRES_NEW 创建一个新事务,如果存在当前事务,则挂起当前事务。
- PROPAGATION_NOT_SUPPORTED 不支持当前事务,始终以非事务方式执行。
- PROPAGATION_NEVER 不支持当前事务,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED 如果当前事务存在,则在嵌套事务中执行,内层事务依赖外层事务,如果外层失败,则会回滚内层,内层失败不影响外层。
Spring 事务传播行为有什么用?这题是群里有位小伙伴遇到的面试题。
其实答案就几个字:控制事务的边界。