1. 实现思路
2.常见面试问题
1.请用自己的语言描述SpringIOC、DI、MVC的基本执行原理。
-
IOC: Inversion of Control(控制反转),作为一个容器,用于保存spring管理的所有对象。
目标:使用SpringIOC容器管理对象。
既然已经有了明确的目标,下一步就应该开始将对象添加到IOC容器中。
步骤:- 1)了解哪些对象需要被spring管理。doScanner方法:读取配置文件或者注解,找到开发者声明的需要依靠spring管理的类,扫描属性(例如 id class init- method scope),记录相应属性,以便DI时可以进行注入。
- 2)将已了解到的需要交给Spring管理的类进行初始化。doInstance方法:按照扫描结果,将对象进行初始化优先使用之前扫描到,声明的beanName,若没有则使用类名首字母小写作为ioc容器中的key,保存到ioc容器中。
-
DI:Dependency Injection(依赖注入),需要使用在springIOC容器中的对象,需要在注解或者配置文声明,当对象之间有依赖关系时,可以利用spring保存的对象关系。
目标:spring保存的对象依赖关系,将对象从IOC容器中取出,进行注入。
既然已经有了明确的目标,下一步就应该从IOC容器中取出对象进行注入。
步骤:- 1)判断哪些对象需要注入。
方法:读取配置文件或者注解(Autowired),判断出需要哪些对象是需要注入的。 - 2)怎么注入。
方法:如果用户有声明beanName,直接从IOC容器中取出相应的对象进行注入,若没有,根据类型进行注入。(此处一个接口只能有一个实现类,若有多个,且都交由spring管理,且未制定beanName,则在IOC步骤就会报错)
- 1)判断哪些对象需要注入。
-
MVC:Model-View-Controller, model:是指模型表示业务规则、View:是指用户看并与之交互的界面、controller:是指控制器接受用户的输入并调用模型和视图去完成用户的需求,MVC的目的:在于将M和V的实现代码分离。而Spring MVC其实做的就是存储url和Method的对应关系,实现传入url调用制定控制器,进行制定业务规则,返回相应的view。
目标:存储url和Method的对应关系,实现传入url调用制定控制器,进行制定业务规则,返回相应的view。
既然已经有了明确的目标,下面聊聊怎么实现。
步骤:- 1)找到需要在handlerMapping中记录的类与方法
方法:扫描注解或者配置文件,读取类以及方法的RequestMapping中的值 - 2)将url和Method的对应关系存储到handlerMapping中
方法:将类的RequestMapping的值+方法的RequestMapping的值拼接作为url,将url作Key,method作值,存储到handlerMapping - 3)用户调用
基于serverlet的实现,在doPost()中执行doDispatch()方法,通过url从handlerMapping中找到指定的方法,使用反射进行调用。
- 1)找到需要在handlerMapping中记录的类与方法
2.Spring中的Bean是线程安全的吗?为什么?。
Spring中的Bean不保证线程安全。
在聊为什么之前,先谈一谈我的理解。
首先我们假定Spring中的Bean是线程安全的,spring需要如何保证Bean的线程安全。作为一个轻量级的框架,spring对于代码的侵入是非常少的,那么想要保证Bean的线程安全,唯一的做法就是在IOC端进行锁的控制。在从IOC容器获取对象之后,加锁。其他类想用?不好意思锁住了,想用就得等我执行完毕,由IOC容器回收,再释放锁之后,你再去抢锁。这样,一个类在执行,其他类就得看着。
这种操作,我认为Spring这么牛X的框架是不可能执行这么蠢的操作的。
那么这么牛X的框架又是怎么做的呢,在初学Spring时了解到作用域(scope)是一个非常重要的概念。spring中为Bean提供了多种作用域给用户做选择,用户可以自己根据业务场景来选择具体的Bean的作用域。并不是所有场景都需要线程安全的Bean的。
scope很好的解决的安全与速度的问题,将安全问题交由用户控制。
1、singleton:单例,默认作用域。
2、prototype:原型,每次创建一个新对象。
3、request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下。
4、session:会话,同一个会话共享一个实例,不同会话使用不用的实例。
5、global-session:全局会话,所有会话共享一个实例。
对于平常写写增删改查涉及到的各种操作,基本涉及到的是无状态的Bean,不用管直接用就是,更本无需担心安全问题,速度也是快得不行。当是一个有状态的Bean,改变scope,用户可以自己来控制对象不会相互影响,在牺牲一部分速度的情况下,就能考虑安全。