十、Spring / Spring MVC
90. 为什么要应用 spring?
1.简介
- 目标:解决企业应用开发的复杂性
- 性能:应用根本的JavaBean代替EJB,并提供了更多的企业应用性能
- 范畴:任何Java利用
简略来说,Spring是一个轻量级的管制反转(IoC)和面向切面(AOP)的容器框架。
2.轻量
从大小与开销两方面而言Spring都是轻量的。残缺的Spring框架能够在一个大小只有1MB多的JAR文件里公布。并且Spring所需的解决开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring利用中的对象不依赖于Spring的特定类。
3.管制反转
Spring通过一种称作管制反转(IoC)的技术促成了松耦合。当利用了IoC,一个对象依赖的其它对象会通过被动的形式传递进来,而不是这个对象本人创立或者查找依赖对象。你能够认为IoC与JNDI相同——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象申请就被动将依赖传递给它。
4.面向切面
Spring提供了面向切面编程的丰盛反对,容许通过拆散利用的业务逻辑与零碎级服务(例如审计(auditing)和事务(transaction)治理)进行内聚性的开发。利用对象只实现它们应该做的——实现业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的零碎级关注点,例如日志或事务反对。
5.容器
Spring蕴含并治理利用对象的配置和生命周期,在这个意义上它是一种容器,你能够配置你的每个bean如何被创立——基于一个可配置原型(prototype),你的bean能够创立一个独自的实例或者每次须要时都生成一个新的实例——以及它们是如何互相关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们常常是宏大与轻便的,难以使用。
6.框架
Spring能够将简略的组件配置、组合成为简单的利用。在Spring中,利用对象被申明式地组合,典型地是在一个XML文件里。Spring也提供了很多根底性能(事务管理、长久化框架集成等等),将应用逻辑的开发留给了你。
所有Spring的这些特色使你可能编写更洁净、更可治理、并且更易于测试的代码。它们也为Spring中的各种模块提供了根底反对。
91. 解释一下什么是 aop?
AOP(Aspect-Oriented Programming,面向方面编程),能够说是OOP(Object-Oriented Programing,面向对象编程)的补充和欠缺。OOP引入封装、继承和多态性等概念来建设一种对象层次结构,用以模仿公共行为的一个汇合。当咱们须要为扩散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP容许你定义从上到下的关系,但并不适宜定义从左到右的关系。例如日志性能。日志代码往往程度地分布在所有对象档次中,而与它所分布到的对象的外围性能毫无关系。对于其余类型的代码,如安全性、异样解决和通明的持续性也是如此。这种分布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的反复,而不利于各个模块的重用。
而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象外部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简略地说,就是将那些与业务无关,却为业务模块所独特调用的逻辑或责任封装起来,便于缩小零碎的反复代码,升高模块间的耦合度,并有利于将来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的办法,就好像一把利刃,将这些空心圆柱体剖开,以取得其外部的音讯。而剖开的切面,也就是所谓的“方面”了。而后它又以巧夺天功的妙手将这些剖开的切面还原,不留痕迹。
应用“横切”技术,AOP把软件系统分为两个局部:外围关注点和横切关注点。业务解决的次要流程是外围关注点,与之关系不大的局部是横切关注点。横切关注点的一个特点是,他们常常产生在外围关注点的多处,而各处都根本类似。比方权限认证、日志、事务处理。Aop 的作用在于拆散零碎中的各种关注点,将外围关注点和横切关注点拆散开来。正如Avanade公司的高级计划构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供反对的通用服务进行拆散。”
92. 解释一下什么是 ioc?
IOC是Inversion of Control的缩写,少数书籍翻译成“管制反转”。
1996年,Michael Mattson在一篇无关探讨面向对象框架的文章中,首先提出了IOC 这个概念。对于面向对象设计及编程的根本思维,后面咱们曾经讲了很多了,不再赘述,简略来说就是把简单零碎分解成相互合作的对象,这些对象类通过封装当前,外部实现对外部是通明的,从而升高了解决问题的复杂度,而且能够灵便地被重用和扩大。
IOC实践提出的观点大体是这样的:借助于“第三方”实现具备依赖关系的对象之间的解耦。如下图:
图 IOC解耦过程
大家看到了吧,因为引进了两头地位的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全副依附“第三方”了,全副对象的控制权全副上缴给“第三方”IOC容器,所以,IOC容器成了整个零碎的要害外围,它起到了一种相似“粘合剂”的作用,把零碎中的所有对象粘合在一起发挥作用,如果没有这个“粘合剂”,对象与对象之间会彼此失去分割,这就是有人把IOC容器比喻成“粘合剂”的由来。
咱们再来做个试验:把上图两头的IOC容器拿掉,而后再来看看这套零碎:
图 拿掉IOC容器后的零碎
咱们当初看到的画面,就是咱们要实现整个零碎所须要实现的全部内容。这时候,A、B、C、D这4个对象之间曾经没有了耦合关系,彼此毫无分割,这样的话,当你在实现A的时候,基本无须再去思考B、C和D了,对象之间的依赖关系曾经升高到了最低水平。所以,如果真能实现IOC容器,对于零碎开发而言,这将是一件如许美妙的事件,参加开发的每一成员只有实现本人的类就能够了,跟他人没有任何关系!
咱们再来看看,管制反转(IOC)到底为什么要起这么个名字?咱们来比照一下:
软件系统在没有引入IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者运行到某一点的时候,本人必须被动去创建对象B或者应用曾经创立的对象B。无论是创立还是应用对象B,控制权都在本人手上。
软件系统在引入IOC容器之后,这种情景就齐全扭转了,如图3所示,因为IOC容器的退出,对象A与对象B之间失去了间接分割,所以,当对象A运行到须要对象B的时候,IOC容器会被动创立一个对象B注入到对象A须要的中央。
通过前后的比照,咱们不难看出来:对象A取得依赖对象B的过程,由被动行为变为了被动行为,控制权颠倒过去了,这就是“管制反转”这个名称的由来。
93. spring 有哪些次要模块?
Spring框架至今已集成了20多个模块。这些模块次要被分如下图所示的外围容器、数据拜访/集成,、Web、AOP(面向切面编程)、工具、音讯和测试模块。
更多信息:howtodoinjava.com/java-spring-framework-tutorials/
94. spring 罕用的注入形式有哪些?
Spring通过DI(依赖注入)实现IOC(管制反转),罕用的注入形式次要有三种:
- 构造方法注入
- setter注入
- 基于注解的注入
95. spring 中的 bean 是线程平安的吗?
Spring容器中的Bean是否线程平安,容器自身并没有提供Bean的线程安全策略,因而能够说spring容器中的Bean自身不具备线程平安的个性,然而具体还是要联合具体scope的Bean去钻研。
96. spring 反对几种 bean 的作用域?
当通过spring容器创立一个Bean实例时,不仅能够实现Bean实例的实例化,还能够为Bean指定特定的作用域。Spring反对如下5种作用域:
- singleton:单例模式,在整个Spring IoC容器中,应用singleton定义的Bean将只有一个实例
- prototype:原型模式,每次通过容器的getBean办法获取prototype定义的Bean时,都将产生一个新的Bean实例
- request:对于每次HTTP申请,应用request定义的Bean都将产生一个新实例,即每次HTTP申请将会产生不同的Bean实例。只有在Web利用中应用Spring时,该作用域才无效
- session:对于每次HTTP Session,应用session定义的Bean豆浆产生一个新实例。同样只有在Web利用中应用Spring时,该作用域才无效
- globalsession:每个全局的HTTP Session,应用session定义的Bean都将产生一个新实例。典型状况下,仅在应用portlet context的时候无效。同样只有在Web利用中应用Spring时,该作用域才无效
其中比拟罕用的是singleton和prototype两种作用域。对于singleton作用域的Bean,每次申请该Bean都将取得雷同的实例。容器负责跟踪Bean实例的状态,负责保护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域,程序每次申请该id的Bean,Spring都会新建一个Bean实例,而后返回给程序。在这种状况下,Spring容器仅仅应用new 关键字创立Bean实例,一旦创立胜利,容器不在跟踪实例,也不会保护Bean实例的状态。
如果不指定Bean的作用域,Spring默认应用singleton作用域。Java在创立Java实例时,须要进行内存申请;销毁实例时,须要实现垃圾回收,这些工作都会导致系统开销的减少。因而,prototype作用域Bean的创立、销毁代价比拟大。而singleton作用域的Bean实例一旦创立胜利,能够重复使用。因而,除非必要,否则尽量避免将Bean被设置成prototype作用域。
97. spring 主动拆卸 bean 有哪些形式?
Spring容器负责创立应用程序中的bean同时通过ID来协调这些对象之间的关系。作为开发人员,咱们须要通知Spring要创立哪些bean并且如何将其拆卸到一起。
spring中bean拆卸有两种形式:
- 隐式的bean发现机制和主动拆卸
- 在java代码或者XML中进行显示配置
当然这些形式也能够配合应用。
98. spring 事务实现形式有哪些?
- 编程式事务管理对基于 POJO 的利用来说是惟一抉择。咱们须要在代码中调用beginTransaction()、commit()、rollback()等事务管理相干的办法,这就是编程式事务管理。
- 基于 TransactionProxyFactoryBean 的申明式事务管理
- 基于 @Transactional 的申明式事务管理
- 基于 Aspectj AOP 配置事务
99. 说一下 spring 的事务隔离?
事务隔离级别指的是一个事务对数据的批改与另一个并行的事务的隔离水平,当多个事务同时拜访雷同数据时,如果没有采取必要的隔离机制,就可能产生以下问题:
- 脏读:一个事务读到另一个事务未提交的更新数据。
- 幻读:例如第一个事务对一个表中的数据进行了批改,比方这种批改波及到表中的“全副数据行”。同时,第二个事务也批改这个表中的数据,这种批改是向表中插入“一行新数据”。那么,当前就会产生操作第一个事务的用户发现表中还存在没有批改的数据行,就好象产生了幻觉一样。
- 不可反复读:比方说在同一个事务中先后执行两条截然不同的select语句,期间在此次事务中没有执行过任何DDL语句,但先后失去的后果不统一,这就是不可反复读。
100. 说一下 spring mvc 运行流程?
Spring MVC运行流程图:
Spring运行流程形容:
- 用户向服务器发送申请,申请被Spring 前端管制Servelt DispatcherServlet捕捉;
2. DispatcherServlet对申请URL进行解析,失去申请资源标识符(URI)。而后依据该URI,调用HandlerMapping取得该Handler配置的所有相干的对象(包含Handler对象以及Handler对象对应的拦截器),最初以HandlerExecutionChain对象的模式返回;
3. DispatcherServlet 依据取得的Handler,抉择一个适合的HandlerAdapter;(附注:如果胜利取得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)办法)
- 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,依据你的配置,Spring将帮你做一些额定的工作:
- HttpMessageConveter: 将申请音讯(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
- 数据转换:对申请音讯进行数据转换。如String转换成Integer、Double等
- 数据根式化:对申请音讯进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
- 数据验证: 验证数据的有效性(长度、格局等),验证后果存储到BindingResult或Error中
- Handler执行实现后,向DispatcherServlet 返回一个ModelAndView对象;
- 依据返回的ModelAndView,抉择一个适宜的ViewResolver(必须是曾经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
7. ViewResolver 联合Model和View,来渲染视图;
- 将渲染后果返回给客户端。
101. spring mvc 有哪些组件?
Spring MVC的外围组件:
- DispatcherServlet:地方控制器,把申请给转发到具体的管制类
- Controller:具体解决申请的控制器
- HandlerMapping:映射处理器,负责映射中央处理器转发给controller时的映射策略
- ModelAndView:服务层返回的数据和视图层的封装类
- ViewResolver:视图解析器,解析具体的视图
- Interceptors :拦截器,负责拦挡咱们定义的申请而后做解决工作
102. @RequestMapping 的作用是什么?
RequestMapping是一个用来解决申请地址映射的注解,可用于类或办法上。用于类上,示意类中的所有响应申请的办法都是以该地址作为父门路。
RequestMapping注解有六个属性,上面咱们把她分成三类进行阐明。
value, method:
- value:指定申请的理论地址,指定的地址能够是URI Template 模式(前面将会阐明);
- method:指定申请的method类型, GET、POST、PUT、DELETE等;
consumes,produces
- consumes:指定解决申请的提交内容类型(Content-Type),例如application/json, text/html;
- produces:指定返回的内容类型,仅当request申请头中的(Accept)类型中蕴含该指定类型才返回;
params,headers
- params: 指定request中必须蕴含某些参数值是,才让该办法解决。
- headers:指定request中必须蕴含某些指定的header值,能力让该办法解决申请。
103. @Autowired 的作用是什么?