它是一个一站式(full-stack全栈式)框架,提供了从表现层-springMVC到业务层-spring再到持久层-springdata的一套完整的解决方案。我们在项目中可以只使用spring一个框架,它就可以提供表现层的mvc框架,持久层的Dao框架。它的两大核心IoC和AOP更是为我们的程序解耦和代码简洁易维护提供了支持。
1)降低了组件之间的耦合性 ,实现了软件各层之间的解耦
2)可以使用很多服务,如事务管理,消息服务等
3)容器提供单例模式支持
4)容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能
5)容器提供了很多辅助类,能加快应用的开发
6)spring对于主流的应用框架提供了集成支持,如hibernate,Struts等
7)spring属于低侵入式设计,代码的污染极低
8)独立于各种应用服务器
9)spring的DI机制降低了业务对象替换的复杂性
10)Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring 的部分或全部
事务就是对一系列数据库的操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。这样可以防止出现脏数据,防止数据库数据出现问题。
例子:比如转账,我本来有200块,你有100。然后我转给你100,如果转账成功,那我就还有100,你有200。这就是事务成功。如果转账失败我还有100,但是你又没收到,就是事务失败了,就要进行事务回滚。要么就是转账操作全部成功,要么就是全部失败。
保证数据的一致性和完整性
1)编程式事务,在代码中硬编码。(不推荐使用)
2)声明式事务,在配置文件中配置(推荐使用)
声明式事务又分为两种:
a)基于XML的声明式事务
b)基于注解的声明式事务
Spring封装了一些注解,比如@Controller注解、@Service注解、@Autowired注解,在类或者属性头顶声明引入,就可以把实例化表现层Bean、业务层Bean的工作交给Spring,而且这些注解指定了实例化的类或者属性的name属性,所以我们就可以直接在Controller层调用Service层,Spring会根据name自动帮我们注入实例,然后就可以执行SQL,操作数据库。通过IOC,可以调用Spring本身已经封装好的注解,帮我们进行依赖注入,我们不需要去管注解具体实现的细节,把控制权交给Spring,等着它自动实例化好对象,我们就可以直接使用了,所以这就是Spring的核心思想--控制反转IOC。
在没有使用IOC之前,我们需要自己主动去new一个实例化对象,自己去声明这个Bean是哪个类的,我们自己手动进行依赖注入,这就是DI。用得比较多是在以前学SSH的时候,需要自己另外写一个application.xml文件,然后里面配置每个Action对应的Service,每个Service对应的Dao,接着在表现层里面再自己new一个实例化对象,new完了要调用业务层的方法了,又在业务层new一个实例化对象,就很麻烦。
此处也可以把面试方向引到SSH对比SSM,详细对比文章链接:https://blog.csdn.net/qq_36688143/article/details/82753975
而关于注解,官方的解释就是说注解是一系列元数据,它提供数据用来解释程序代码,但是注解并不是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。注解可以提供信息给编译器,也可以在程序编译阶段或者运行阶段对信息进行处理。
这个解释我觉得太绕了,我自己的理解就是注解就相当于标签,它就是用来解释代码的,它的语法也很简单,只是在接口关键字前面加了一个@符号。而元注解就是一个特殊的标签,这个特殊的标签可以贴在普通标签上。类比过来的话,元注解就是注解到注解上的注解,它就是专门贴在注解上的。然后关于注解的使用,它可以有默认值,在引入的时候就可以直接赋值。通过Class的反射我们可以获取到注解,然后调用方法判断返回值,就可以使用注解封装的属性和方法了。那这样子的话,我有想过如果给每个类,每个属性都贴上标签,大量使用注解,那代码敲起来不是很方便了?(这个可以放在面试的最后,面试官问:你还有什么想问的吗?提出来)
后来我感觉这肯定是不行的,就去百度过这个问题,了解到注解的提取需要借助Java的反射机制,然后反射又比较慢,大量使用注解的话,时间成本就会上去,也就是说使用注解的时候需要考虑到时间成本。
AOP核心思想:程序中一些冗余代码分散在各方法的横切面上,比如log日志,造成了代码重复,也不利于各个模块的重用。AOP就是把逻辑代码和琐碎事务分开,提高程序扩展性,方便添加其他事物。它利用一种称为“横切”的技术,切开封装的对象内部,把那些影响了多个类的公共行为封装到一个可重用模块,并称为“Aspect”,即方面。Aspect“方面”就是将那些和业务无关,却被业务模块共同调用的逻辑封装起来,减少系统的重复代码,降低模块间的耦合度,并提高代码的可操作性和可维护性。AOP代表的是一种横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向切面编程就是一把刀,把对象的空心圆柱体切开,来获得其内部的消息内容。而切开的切面,就是Aspect,然后AOP又把切面复原。原来的类和方法本身没有影响,但是AOP可以通过嵌入的自定义方法控制类和方法的返回结果。
①动态代理对象的生成,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行
②静态织入的方式,引入特定的语法创建Aspect“方面”,从而使得编译器可以在编译期间织入有关Aspect“方面”的代码
①通过配置文件xml,比如
②编程的方式,在运行的时候动态的将代码切入到类的指定方法、指定位置上
1.它是基于组件技术的全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件,并且和Spring提供的其他基础结构紧密集成
2.不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的)
3.可以任意使用各种视图技术,而不仅仅局限于JSP
4.支持各种请求资源的映射策略
5.易于扩展
简单描述SpringMVC,不含各种名词,适合回答的时候对实际原理不清晰和英语差的iphone xr 64G穷人版:
(1)客户端通过url发送请求
(2-3)核心控制器Dispatcher Servlet接收到请求,通过系统或自定义的映射器配置找到对应的handler,并将url映射的控制器controller返回给核心控制器。
(4)通过核心控制器找到系统或默认的适配器
(5-7)由找到的适配器,调用实现对应接口的处理器,并将结果返回给适配器,结果中包含数据模型和视图对象,再由适配器返回给核心控制器
(8-9)核心控制器将获取的数据和视图结合的对象传递给视图解析器,获取解析得到的结果,并由视图解析器响应给核心控制器
(10)核心控制器将结果返回给客户端
下面这个是iphone xs max 256G版土豪版,有实力的可以回答这个:
1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet.
2、DipatcherServlet接收到这个请求之后将根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandlerMapping的配置找到处理请求的处理器(Handler)。
3-4、DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。
5、Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。
6、Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。
7、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。
组件名词解释:
1.DispatcherServlet:前端控制器,等同于以前的Controller, 是整个流程的中心, 负责调用其他组件
2.HandlerMapping: 处理器映射器,负责根据请求找到Handler(处理器),springMVC中可以根据不同的映射器实现不同映射,比如 xml配置方式,注解方式,接口方式等
3.Handler:后端控制器,在前端控制器的控制下对具体的用户请求进行处理,所以一般情况下都需要开发者进行根据需求进行开发。
4.HandlerAdapter:处理器适配器,处理Handler,可以对多种类型的处理器进行执行,这是对适配器模式的应用体现。
5.ViewResolver : 视图解析器,负责将处理结果生成view视图、开发者可以根据需要开发view