SSM面试题
目录
- Spring的IoC理解
- Ioc 配置的三种方式
- 如何理解Spring中的依赖注入(DI)
- Spring框架的常用注解有哪些
- Spring 中@Autowired 和@Resource 的区别
- Spring的AOP理解
- Spring Bean的生命周期
- Spring 中用到了那些设计模式
- 什么是Spring MVC
- 描述Spring MVC的处理流程
- SpringMVC怎么样设定重定向和转发的
- SpringMVC常用的注解有哪些
- 什么是Mybatis
- #{}和${}的区别是什么
- Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复
- Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
- Mybatis的一级、二级缓存?
Spring的IoC理解
- IOC(Inversion of Control)控制反转,是一种思想,指将对象的控制权转移给Spring框架,由 Spring 来负责控制对象的生命周期(比如创建、销毁)和对象间的依赖关系
- 实现原理:工厂模式加反射机制,把创建对象代码从具体类中剥离出去,交由工厂来完成,
- 优点:降低代码间的依赖关系,削减程序中的耦合
Ioc 配置的三种方式
- xml 配置
- Java 配置(创建一个配置类, 添加@Configuration注解声明为配置类)
- 注解配置(对类添加@Component相关的注解,比如@Controller,@Service,@Repository)
- 主流方式:注解 + Java 配置
如何理解Spring中的依赖注入(DI)
DI:让spring框架给Bean对象的属性进行赋值,把持久层对象传入业务层,而不用我们自己去获取,它是 spring 框架核心 Ioc 的具体实现
- 依赖注入的几种方式:
- (1)使用构造方法注入(XML中constructor-arg 属性)
- (2)setter注入(XML中property属性)
- (3)基于注解的注入(@Autowired)
Spring框架的常用注解有哪些
- pojo实例化
- @Component:将普通pojo实例化到spring容器中,相当于
<bean id="" class=""
- @Controller:控制器层
- @Service:服务层用
- @Repository:持久层用
- 依赖注入注解
- @Autowired注解:按类型注入
- @Qualifier("id") 注解:按照id注入
- @Resource注解:可按照name
- 其它
- @Configuration标识当前类是Spring的一个配置类
- @ComponentScan替代xml中的
<context:component-scan/>
- @Import引入其他配置类,被引入的配置类可以不加@Configuration注解
- @Value对成员变量赋值
- @Bean将一个方法的返回值对象加入到Spring的容器当中管理
- @Qualifier可以使用在方法参数上,表明对应的形参引入/注入的对象类型
Spring 中@Autowired 和@Resource 的区别
- @Autowired 默认的是按照类型进行注入, 如果没有类型会按照名称进行注入,如果想直接按照名称注入需要加入@Qualifier("xxxDao")
- @Resource 默认的会按照名称(name)注入,名称找不着会按照类型来找,如果这里写了name,就直接按照名称找,不会按类型找
Spring的AOP理解
将我们程序重复的代码抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),是OOP的一种延续,用于权限认证、日志、事务处理
- 优点:提高代码的可重用性,使编码更加简洁,更易于维护
Spring Bean的生命周期
四个阶段:
- 实例化 Instantiation --> 属性赋值 Populate --> 初始化 Initialization --> 销毁 Destruction
Spring 中用到了那些设计模式
- 代理模式—在AOP和remoting中被用的比较多
- 单例模式—在spring配置文件中定义的bean默认为单例模式
- 模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate
- 工厂模式—BeanFactory用来创建对象的实例
什么是Spring MVC
基于Java 的实现了Web MVC 设计模式的请求驱动类型(请求-响应模型)的轻量级Web 框架,即使用了MVC 架构模式的思想,将 web 层进行职责解耦,框架的目的就是帮助我们简化开发
描述Spring MVC的处理流程
- 第一步:用户发送请求至前端控制器(DispatcherServlet)
- 第二步:DispatcherServlet收到请求调用映射处理器(HandlerMapping),请求获取Handler处理器(页面控制器)
- 第三步:映射处理器(HandlerMapping)根据请求Url找到,具体的Handler处理器(页面控制器),生成HandlerExecutionChain对象(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)一并返回DispatcherServlet
- 第四步:DispatcherServlet调用适配器(HandlerAdapter)将Handler处理器(页面控制器)包装为适配器
- 第五步:适配器(HandlerAdapter)根据适配的结果调用真正的Handler处理器(页面控制器)的功能处理方法
- 第六步:Handler处理器(页面控制器)执行完成返回ModelAndView给适配器(HandlerAdapter)
- 第七步:适配器(HandlerAdapter)向前端控制器(DispatcherServlet)返回 ModelAndView(ModelAndView 是SpringMVC 框架的一个底层对象,包括 Model模型数据 和 View逻辑视图名)
- 第八步:前端控制器(DispatcherServlet)请求视图解析器(ViewResolver)去进行视图解析,根据逻辑视图名来解析真正的视图。
- 第九步:视图解析器(ViewResolver)向前端控制器(DispatcherServlet)返回View
- 第十步:前端控制器(DispatcherServlet)进行视图渲染,就是将模型数据(在 ModelAndView 对象中)填充至视图中
- 第十一步:前端控制器(DispatcherServlet)向用户响应结果
SpringMVC怎么样设定重定向和转发的
(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"
(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"
SpringMVC常用的注解有哪些
- @RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径
- @RequestBody:注解实现接收http请求的json数据,将json转换为java对象(GET请求不适用)
- @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户
- @PathVariable:映射 URL 绑定的占位符
- @RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
- @Controller:控制器的注解,可以用@RestController(=@ResponseBody + @Controller)代替
什么是Mybatis
(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建statement等繁杂的过程,开发者开发时只需要关注如何编写SQL语句,可以严格控制sql执行性能,灵活度高
(2)作为一个半ORM框架,MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
#{}和${}的区别是什么
- ${}是字符串替换(直接替换成变量的值),#{}是预处理(会对sql语句进行预处理,将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值)
- 使用#{}可以有效的防止SQL注入,提高系统安全。
Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复
不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复
Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
- 延迟加载的基本原理:使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用
Mybatis的一级、二级缓存?
一级缓存的作用域是一个sqlsession内(默认使用)
- 使用同一个SqlSession对象调用一个Mapper方法查询数据,第一次走数据库,其他都走缓存
- 执行commit(执行插入、更新、删除),则会清空SqlSession中的一级缓存 二级缓存作用域是针对mapper进行缓存(需手动开启)
- 范围是 mapper 级别,基于mapper文件的namespace的,一个名称空间,对应一个二级缓存