基本思想
IOC控制反转
AOP动态代理
AOP的原理是什么?
JDK动态代理和CGLIB动态代理在实现上有什么区别?各有什么优劣
流程以及Bean生命周期
工作流程
SpringMVC工作流程
- 用户向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。
- DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)
- DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller
- HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet
- DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,然后返回真正的视图。
- DispatcherServlet将模型数据填充到视图中
- DispatcherServlet将结果响应给用户
Bean生命周期
Spring Bean 的完整生命周期
- Bean容器/BeanFactory 通过对象的构造器或工厂方法先实例化 Bean;
- 再根据 Resource 中的信息再通过设定好的方法(典型的有setter,统称为BeanWrapper)对 Bean 设置属性值,得到 BeanDefintion 对象,然后 put 到 beanDefinitionMap 中,调用 getBean 的时候,从 beanDefinitionMap 里,拿出 Class 对象进行注入,同时,如果有依赖关系,将递归调用 getBean 方法,即依赖注入的过程。
- 检查 xxxAware 相关接口,比如 BeanNameAware,BeanClassLoaderAware,ApplicationContextAware( BeanFactoryAware)等等,如果有就调用相应的 setxxx 方法把所需要的xxx传入到 Bean 中。
补充:关于 Aware ,Aware 就是感知的意思, Aware 的目的是为了让Bean获得Spring容器的服务。 实现了这类接口的 bean 会存在“意识感”,从而让容器调用 setxxx 方法把所需要的 xxx 传到 Bean 中。 - 此时检查是否存在有于 Bean 关联的任何 BeanPostProcessors, 执行 postProcessBeforeInitialization() 方法(前置处理器)。
- 如果 Bean 实现了InitializingBean接口(正在初始化的 Bean),执行 afterPropertiesSet() 方法。
- 检查是否配置了自定义的 init-method 方法,如果有就调用。
- 此时检查是否存在有于 Bean 关联的任何 BeanPostProcessors, 执行 postProcessAfterInitialization() 方法(后置处理器)。返回 wrapperBean(包装后的 Bean)。
- 这时就可以开始使用 Bean 了,当容器关闭时,会检查 Bean 是否实现了 DisposableBean 接口,如果有就调用 destory() 方法。
- 如果 Bean 配置文件中的定义包含 destroy-method 属性,执行指定的方法。
Spring 是如何解决循环依赖的
三级缓存
Spring注解
@Resource和@Autowired注解有什么区别
一、@Autowired有个required属性,可以配置为false,这种情况下如果没有找到对应的bean是不会抛异常的。@Inject和@Resource没有提供对应的配置,所以必须找到否则会抛异常。
二、 @Autowired和@Inject基本是一样的,因为两者都是使用AutowiredAnnotationBeanPostProcessor来处理依赖注入。但是@Resource是个例外,它使用的是CommonAnnotationBeanPostProcessor来处理依赖注入。当然,两者都是BeanPostProcessor。
@Autowired和@Inject
- 默认 autowired by type
- 可以 通过@Qualifier 显式指定 autowired by qualifier name。
- 如果 autowired by type 失败(找不到或者找到多个实现),则退化为autowired by field name
@Resource
- 默认 autowired by field name
- 如果 autowired by field name失败,会退化为 autowired by type
- 可以 通过@Qualifier 显式指定 autowired by qualifier name
- 如果 autowired by qualifier name失败,会退化为 autowired by field name。但是这时候如果 autowired by field name失败,就不会再退化为autowired by type了。
Spring组件
Filter和Interceptor的区别
Interceptor
主要作用:拦截用户请求,进行处理,比如判断用户登录情况、权限验证,只要针对Controller请求进行处理,是通过HandlerInterceptor
。
Interceptor分两种情况,一种是对会话的拦截,实现spring的HandlerInterceptor接口并注册到mvc的拦截队列中,其中preHandle()
方法在调用Handler之前进行拦截(上图步骤③),postHandle()
方法在视图渲染之前调用(上图步骤⑤),afterCompletion()
方法在返回相应之前执行;另一种是对方法的拦截,需要使用@Aspect
注解,在每次调用指定方法的前、后进行拦截。
Filter
主要作用:过滤字符编码、做一些业务逻辑判断,主要用于对用户请求进行预处理,同时也可进行逻辑判断。
Filter在请求进入servlet容器执行service()方法之前就会经过filter过滤(上图步骤①),不像Intreceptor一样依赖于SpringMVC框架,只需要依赖于servlet。Filter启动是随WEB应用的启动而启动,只需要初始化一次,以后都可以进行拦截。
Filter有如下几个种类:
- 用户授权Filter:检查用户请求,根据请求过滤用户非法请求;
- 日志Filter:记录某些特殊的用户请求;
- 解码Filter:对非标准编码的请求解码。
Filter和Interceptor的区别
- Filter是基于函数回调(doFilter()方法)的,而Interceptor则是基于Java反射的(AOP思想)。
- Filter依赖于Servlet容器,而Interceptor不依赖于Servlet容器。
- Filter对几乎所有的请求起作用,而Interceptor只能对action请求起作用。
- Interceptor可以访问Action的上下文,值栈里的对象,而Filter不能。
- 在action的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。
- Filter在过滤是只能对request和response进行操作,而interceptor可以对request、response、handler、modelAndView、exception进行操作。