SpringMVC工作原理/工作流程
问题回答
-
用户发送请求至前端控制器DispatcherServlet;
-
DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
-
处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并
返回给DispatcherServlet; -
DispatcherServlet 调用 HandlerAdapter处理器适配器;
-
HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
-
Handler执行完成返回ModelAndView;
-
HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
-
DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
-
ViewResolver解析后返回具体View;
10.DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
11.DispatcherServlet响应用户。
简要回答:
- 拦截(需要找web.xml配置)
- 找handler(springmvc干的)
- 调handler(我们写的)
- 返回ModelAndView(我们写的)
- 解析返回View(我们配置的)
- 渲染(springmvc干的)
- 返回(springmvc干的)
看图
核心类
DispatcherServlet、HandlerMapping、HandlerAdapter、Handler、ModelAndView、ViewResolver
SpringMvc常见注解?
问题回答
- @Controller:用于定义控制器类
- @ResponseBody:表示方法的返回结果直接写入HTTP response body中
- @PathVariable:获取路径参数
- @RequestParam:用在方法的参数前面
- @RequestBody:请求的json转化为bean去接收
- @RestController:是@Controller和@ResponseBody的合集
- @RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射
- @GetMapping:是@RequestMapping(method = RequestMethod.GET)的缩写。不支持
- @RequestMapping的自定义属性。
10.@PostMapping:是@RequestMapping(method = RequestMethod.POST)的缩写。不支持
11.@RequestMapping的自定义属性。
12.@ControllerAdvice:统一处理异常。
13.@ExceptionHandler:用在方法上表示遇到这个异常就执行以下方法。
Spring依赖注入有哪些方式?
问题回答
有4种依赖注入方式:
- Set方法注入:注入是最简单、最常用的注入方式,支持注解+xml。
- 构造器注入:是指带有参数的构造函数注入,支持注解+xml。
- 静态工厂的方法注入:通过调用静态工厂的方法来获取自己需要的对象,只支持xml。
- 实例工厂的方法注入:获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法,只支持xml。
有2 种实现方式:
- 注解(如@Autowired,@Resource,@Required)
- 配置文件(如xml)
简要回答
- set注入、构造注入、静态工厂、实例工厂4种注入形式。
- 可以通过注解和xml形式。
- java类提供Bean定义信息。
set-注解方式
set-注解方式
set-xml
set-xml方式
构造-注解方式
构造-注解方式
构造-xml方式
构造-xml方式
静态工厂-xml
静态工厂-xml
实例工厂-xml
实例工厂-xml
了解@bean的方式
@bean的方式
spring框架中bean的作用域有几种?
问题回答
- singleton(单例模式)
- prototype(原型模式)
- request(HTTP请求)
- session(会话)
- global-session(全局会话)
spring用到的设计模式?
问题回答
- 工厂设计模式 : Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
- 代理设计模式 : Spring AOP 功能的实现。
- 单例设计模式 : Spring 中的 Bean 默认都是单例的。
- 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
- 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
- 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
- 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。
ssm-#{}和${}的区别是什么?
问题回答
- #{}是预编译处理,可以有效的防止SQL注入。底层实现依靠PreparedStatement,预编译的时候会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值的时候都会加上2个单引号。
- ${}是直接字符串替换,所以有sql注入的风险。like ,order by ,where
- 两者都可以使用的时候优先用#{},比如where查询,like查询选择用#{}。
- order by 字段,from 表名称,只能用${}。
- #{}可以对数据类型进行自动转换,而${}将所有数据都当做字符串处理
简单回答
- #{}可以防止sql注入
- 能用#{}不用${}
- order by 字段,from 表名称,只能用${}
看代码
ssm-mybatis模糊查询like语句该怎么写?
问题回答
- java中用%,sql使用#{}。建议。
- java中用%,sql使用${}。不建议,会sql注入。
- sql中使用%,sql使用 ${}。不建议,会sql注入。
- sql中使用%,sql使用 #{}。可以,但是需要注意选择合适的引号。
- sql中使用%,sql使用 #{}。配合concat函数,建议。
简要回答
- 不用${},有sql注入风险
- 用 #{},%号在java中或者sql中都可以。sql中使用%,需要配合concat函数。
java中用%,sql使用#{}。建议。
java中用%,sql使用${}。不建议,会sql注入。需要做额外的处理
sql中使用%,sql使用 ${}。不建议,会sql注入。需要做额外的处理
sql中使用%,sql使用 #{}。可以,但是需要注意选择合适的引号
sql中使用%,sql使用 #{}。配合concat函数,可以。
ssm-说一下spring的AOP?
问题回答
- AOP,也就是面向切面编程;其次还有面向过程和面向对象编程。
- Spring AOP实现主要是通过代理类的方式实现,有jdk动态代理和CGLIB代理两种方式。
- Java动态代理只能够对接口进行代理,不能对普通的类进行代理(因为所有生成的代理类的父类为Proxy,Java类继承机制不允许多重继承);CGLIB能够代理普通类;
- Spring内部,发现如果目标对象没有实现接口,则默认会采用CGLIB代理; 如果目标对象实现了接口,默认会采用Java动态代理;
- AOP用到的动态代理是对方法增强的方式之一。
- AOP的典型应用就是事务管理 。
简要回答
- Spring AOP有jdk动态代理方式和CGLIB方式。
- Spring内部,发现目标对象没有实现接口,则用CGLIB。有接口则用Java动态代理。
- AOP的典型应用就是事务管理
验证Java动态代理只能够对接口进行代理,不能对普通的类进行代理
来一个动态代理的案例
运行结果
用everyThing找到$Proxy0.class
使用idea打开,查看结果,继承了Proxy,java单继承,所以验证了我们的结论。
对java方法进行功能增强的三种方法
-
通过继承的方式
对哪个类中的方法进行增强,可以采用继承那个类的方式。通过继承该类,可以重写方法,如果还需要老方法的一些功能,使用super调用。 -
通过装饰者模式
需要对某接口或抽象类的实现类中重写的方法进行功能增强可以使用装饰者模式。 -
动态代理
ssm-说说spring的事务管理?
问题回答
- spring支持编程式事务管理和声明式事务管理两种方式
- 现在主流的是声明式事务管理方式,分为基于 和 命名空间的声明式事务管理和基于 @Transactional 的方式将声明式事务管理
- 基于 和 命名空间的声明式事务,可以充分利用切点表达式的强大支持,使得管理事务更加灵活。
- 基于 @Transactional 的方式将声明式事务管理,简化到了极致。开发人员只需在配置文件中加上一行配置,然后在需要实施事务管理的方法或者类上使用 @Transactional 指定事务规则即可实现事务管理
- 声明式事务,是建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
- 声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
简要回答
- spring支持编程式事务管理和声明式事务管理两种方式
- 声明式事务管理分为基于 和 命名空间的声明式事务管理和基于 @Transactional 的方式将声明式事务管理
基于@Transactional事务管理
基于tx和aop名字空间的xml配置式
springBoot中使用@Transactional
1. @Transactional 注解只能应用到 public 方法才有效
- spring boot 会自动配置一个 DataSourceTransactionManager,我们只需在方法(或者类)加上 @Transactional 注解,就自动纳入 Spring 的事务管理了。
如下有一个保存用户的方法,加入 @Transactional 注解,使用默认配置,抛出异常之后,事务会自动回滚,数据不会插入到数据库
使用Spring框架的好处是什么?
问题回答
- 轻量:Spring 是轻量级,无侵入。
- 控制反转(IOC):Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
- 面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
- 容器:Spring 包含并管理应用中对象的生命周期和配置。
- MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
- 事务管理:Spring 提供一个持续的事务管理接口,可以通过配置文件或者注解轻松实现。
- 异常处理:Spring提供了全局异常处理功能,只需要声明一个全局异常处理器就可以捕获所有异常信息。
简化记忆
- 轻量
- 控制反转 ioc
- 面向切面编程 aop
- 容器
- mvc框架
- 事务管理
- 异常处理
知道spring的前身
所谓轻量级就是spring框架在系统初始化的时候不用加载所有的服务,为系统节约了资源!而EJB框架就是重量级的,每次初始化都必须加载所有的服务!
2.知道耦合度、松耦合、紧耦合、解耦
耦合度就是对象之间的依赖性
松耦合:A和B分别独立实现,各自执行独立的功能,代码中没有互相调用,如果需要互相配合,则由第三者来控制它们之间的互相访问。Spring应用中的第三方就是Spring容器。
紧耦合方式:A和B分别独立实现,但二者之间可以互相访问。
3.知道除了mvc还有mvvm和mvp
mvc:spring
mvvm:vue
mvp:android
4.回顾spring的异常处理
全局异常类,类上添加@ControllerAdvice和@ResponseBody返回json参数。也可以单独使用@RestControllerAdvice。且spring会扫描到此注解,所以无需配置注入bean
在方法上添加@ExceptionHander(value = “需拦截异常的class”),可以单独拦截某一个异常,也可以全拦截Excepiton。
谈谈spring的IOC和DI
问题回答
- Ioc,控制反转;DI,依赖注入。
- Ioc意味着将你设计好的对象交给容器控制(创建,销毁,调用)。
- Di是组件之间依赖关系由容器在运行期决定
- Ioc和DI其实是一种思想,并不是具体的技术。
- IoC 和 DI 有什么关系呢?其实它们是同一个概念的不同角度描述。由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”。相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
- 最直接看到的效果就是,少New了几个类,基本看不到New关键字了。
- 比如,创建数据库连接上,整个项目创建连接时并不是当需要连接时new一个连接,而是项目在配置的时候创建好连接,当要用的时候,DI会给程序去用,而程序在什么时候用和怎么用时开发者不知道的,但最后还是实现了功能。
简要回答
- Ioc,控制反转;DI,依赖注入。
- 基本看不到New关键字了,对象的创建,销毁,调用都交给了Spring容器。
- Ioc和Di可以理解为同一个概念,都是一种编程思想。