目录
1.3 springMVC常用的注解有哪些?都是用来做什么的?
2.4 spring有几种配置方式?如何基于XML配置文件方式来配置spring?
2.8 Spring 单例bean线程安全问题(为什么存在线程安全问题?解决方案)
2.9 spring的@Component和@Bean的区别是什么?
2.10 spring中将一个类声明为一个Bean的注解有哪些?
3.3 为什么说mybatis是半自动ORM框架,他与全自动的有什么区别?
3.5 使用mybatis的mapper调用接口时有哪些要求?
1 springMVC
1.1 springmvc的工作流程
前端控制器->处理器映射器->处理器适配器->视图解析器->返回具体view->渲染
1)用户发送请求至前端控制器 DispatcherServlet。
2)DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
3)处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象 及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
4)DispatcherServlet 调用 HandlerAdapter 处理器适配器。
5)HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)。
6)Controller 执行完成返回 ModelAndView。
7)HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。
8)DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
9)ViewReslover 解析后返回具体 View。
10)DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
11)DispatcherServlet 响应用户。
或者
1、DispatcherServlet前端控制器接收发过来的请求,交给HandlerMapping处理器映射器
2、HandlerMapping处理器映射器,根据请求路径找到相应的HandlerAdapter处理器适配器(处理器适配器就是那些拦截器或Controller)
3、HandlerAdapter处理器适配器,处理一些功能请求,返回一个ModelAndView对象(包括模型数据、逻辑视图名)
4、ViewResolver视图解析器,先根据ModelAndView中设置的View解析具体视图
5、然后再将Model模型中的数据渲染到View上
1.2 springMVC的主要组件
1)前端控制器 DispatcherServlet(不需要程序员开发)
作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
(2)处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的URL来查找Handler
(3)处理器适配器HandlerAdapter
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
(4)处理器Handler(需要程序员开发)
(5)视图解析器 ViewResolver(不需要程序员开发)
作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)
(6)视图View(需要程序员开发jsp)
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
1.3 springMVC常用的注解有哪些?都是用来做什么的?
2 Spring
2.1 简述Spring的AOP和IOC
---IOC(Inversion Of Controll,控制反转)是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由给Spring框架来管理。IOC容器是Spring用来实现IOC的载体,IOC容器实际上就是一个Map(key, value),Map中存放的是各种对象。
将对象之间的相互依赖关系交给IOC容器来管理,并由IOC容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。IOC容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。在实际项目中一个Service类可能由几百甚至上千个类作为它的底层,假如我们需要实例化这个Service,可能要每次都搞清楚这个Service所有底层类的构造函数,这可能会把人逼疯。如果利用IOC的话,你只需要配置好,然后在需要的地方引用就行了,大大增加了项目的可维护性且降低了开发难度。
Spring时代我们一般通过XML文件来配置Bean,后来开发人员觉得用XML文件来配置不太好,于是Sprng Boot注解配置就慢慢开始流行起来。
---AOP(Aspect-Oriented Programming,面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。
Spring AOP是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP就会使用JDK动态代理去创建代理对象;而对于没有实现接口的对象,就无法使用JDK动态代理,转而使用CGlib动态代理生成一个被代理对象的子类来作为代理。
2.2 IOC容器对bean的生命周期
Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务。
Spring IOC容器对Bean的生命周期进行管理的过程如下:
通过构造器或工厂方法创建Bean实例
为Bean的属性设置值和对其它Bean的引用
调用Bean的初始化方法
Bean可以使用了
当容器关闭时,调用Bean的销毁方法
在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法。
方法管理 bean 生命周期的代码样例如下:
2.3 使用spring框架能带来什么好处
1.方便解耦,便于开发(Spring就是一个大工厂,可以将所有对象的创建和依赖关系维护都交给spring管理)
2.spring支持aop编程(spring提供面向切面编程,可以很方便的实现对程序进行权限拦截和运行监控等功能)
3.声明式事务的支持(通过配置就完成对事务的支持,不需要手动编程)
4.方便程序的测试,spring 对junit4支持,可以通过注解方便的测试spring 程序
5.方便集成各种优秀的框架()
6.降低javaEE API的使用难度(Spring 对javaEE开发中非常难用的一些API 例如JDBC,javaMail,远程调用等,都提供了封装,是这些API应用难度大大降低)
2.4 spring有几种配置方式?如何基于XML配置文件方式来配置spring?
Xml、java、注解
在 Spring 框架中,依赖和服务需要在专门的配置文件来实现,我常用的 XML 格式的配置文件。这 些配置文件的格式通常用开头,然后一系列的 bean 定义和专门的应用配置 选项组成。
SpringXML 配置的主要目的时候是使所有的 Spring 组件都可以用 xml 文件的形式来进行配置。这 意味着不会出现其他的 Spring 配置类型(比如声明的方式或基于 Java Class 的配置方式)
Sprin的 XML 配置方式是使用被 Spring 命名空间的所支持的一系列的 XML 标签来实现的。 Spring 有以下主要的命名空间:context、beans、jdbc、tx、aop、mvc 和 aso。
2.5 spring事务管理的方式有几种?
1.编程式事务:在代码中硬编码(不推荐使用)。
2.声明式事务:在配置文件中配置(推荐使用),分为基于XML的声明式事务和基于注解的声明式事务。
2.6 Spring bean的作用域之间有什么区别
Spring 容器中的 bean 可以分为 5 个范围。所有范围的名称都是自说明的,但是为了避免混淆,还是让我们来解释一下:
1. singleton:这种 bean 范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个 bean 的实例,单例的模式由 bean factory 自身来维护。
2. prototype:原形范围与单例范围相反,为每一个 bean 请求提供一个实例。
3. request:在请求 bean 范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后, bean 会失效并被垃圾回收器回收。
4. Session:与请求范围类似,确保每个 session 中有一个 bean 的实例,在 session 过期后,bean 会随之失效。
5. global- session:global-session 和 Portlet 应用相关。当你的应用部署在 Portlet 容器中工作 时,它包含很多 portlet。如果 你想要声明让所有的 portlet 共用全局的存储变量的话,那么这全 局变量需要存储在 global-session 中。 全局作用域与 Servlet 中的 session 作用域效果相同。
2.7 spring框架中都用哪些设计模式
1.工厂设计模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。
2.代理设计模式:Spring AOP功能的实现。
3.单例设计模式:Spring中的bean默认都是单例的。
4.模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。
5.包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
6.观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。
7.适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。
2.8 Spring 单例bean线程安全问题(为什么存在线程安全问题?解决方案)
线程安全问题都是由成员变量及静态变量引起的。
若每个线程中对成员变量、静态变量只有读操作,而无写操作,一般来说,这个成员变量、静态变量是线程安全的;
若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
当多个线程调用方法时会不会出现线程安全问题呢?答案是不会,方法存在虚拟机栈中,是线程私有的。
有两种常见的解决方案:
1.在bean对象中尽量避免定义可变的成员变量(不太现实)。
2.在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中(推荐的一种方式)。
2.9 spring的@Component和@Bean的区别是什么?
1.作用对象不同。@Component注解作用于类,而@Bean注解作用于方法。
2.@Component注解通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用@ComponentScan注解定义要扫描的路径)。@Bean注解通常是在标有该注解的方法中定义产生这个bean,告诉Spring这是某个类的实例,当我需要用它的时候还给我。
3.@Bean注解比@Component注解的自定义性更强,而且很多地方只能通过@Bean注解来注册bean。比如当引用第三方库的类需要装配到Spring容器的时候,就只能通过@Bean注解来实现。
2.10 spring中将一个类声明为一个Bean的注解有哪些?
1.@Component注解。通用的注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪一个层,可以使用@Component注解标注。
2.@Repository注解。对应持久层,即Dao层,主要用于数据库相关操作。
3.@Service注解。对应服务层,即Service层,主要涉及一些复杂的逻辑,需要用到Dao层(注入)。
4.@Controller注解。对应Spring MVC的控制层,即Controller层,主要用于接受用户请求并调用Service层的方法返回数据给前端页面。
2.11 spring的事务隔离级别有几种?
在TransactionDefinition接口中定义了五个表示隔离级别的常量:
1) DEFAULT (默认)
这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。
2) READ_UNCOMMITTED (读未提交)
这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
3) READ_COMMITTED (读已提交)
保证一个事务修改的数据提交后才能被另外一个事务读取,另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
4) REPEATABLE_READ (可重复读)
这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读。
5) SERIALIZABLE(串行化)
这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读、不可重复读外,还避免了幻像读。
3 Mybatis
3.1 说一下mybatis的缓存
答:Mybatis 中有一级缓存和二级缓存,默认情况下一级缓存是开启的,而且是不能关闭的。一级缓存 是指 SqlSession 级别的缓存,当在同一个 SqlSession 中进行相同的 SQL 语句查询时,第二次以 后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存 1024 条 SQL。
二级缓存 是指可以跨 SqlSession 的缓存。是 mapper 级别的缓存,对于 mapper 级别的缓存不同的 sqlsession 是可以共享的。
3.2 mybatis中的 #{} 和 ${} 的区别
1、#{ }是预编译处理,MyBatis在处理#{ }时,它会将sql中的#{ }替换为?,然后调用PreparedStatement的set方法来赋值,传入字符串后,会在值两边加上单引号,如上面的值 “4,44,514”就会变成“ '4,44,514' ”;
2、${ }是字符串替换,在处理{ }是字符串替换, MyBatis在处理{ }时,它会将sql中的${ }替换为变量的值,传入的数据不会加两边加上单引号。
都是mybatis的占位符,最大的区别在于防止sql注入 一般都是用#{}
知识点:sq注入
就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。常见的有匿名登录(在登录框输入恶意的字符串)、借助异常获取数据库信息等
3.3 为什么说mybatis是半自动ORM框架,他与全自动的有什么区别?
答:Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象 时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis 在查询关联对象或 关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。
mybatis绑定sql的方式有几种?你一般是怎么使用的?
Xml、注解
简单查询,比如单表查询使用注解模式开发;
复杂查询,比如多表查询使用xml配置文件模式开发。
3.4 mybatis和Hibernate的区别?
答:
1)Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要程序员自己 编写 Sql 语句,不过 mybatis 可以通过 XML 或注解方式灵活配置要运行的 sql 语句,并将 java 对象和 sql 语句映射生成最终执行的 sql,最后将 sql 执行的结果再映射生成 java 对 象。
2)Mybatis 学习门槛低,简单易学,程序员直接编写原生态 sql,可严格控制 sql 执行性 能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运 营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的 前提是 mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定 义多套 sql 映射文件,工作量大。
3)Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如 需求固定的定制化软件)如果用 hibernate 开发可以节省很多代码,提高效率。但是 Hibernate 的缺点是学习门槛高,要精通门槛更高,而且怎么设计 O/R 映射,在性能和对象 模型之间如何权衡,以及怎样用好 Hibernate 需要具有很强的经验和能力才行。 总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都 是好架构,所以框架只有适合才是最好。
3.5 使用mybatis的mapper调用接口时有哪些要求?
答:
1)Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同
2)Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的 类型相同
3)Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型 相同
4)Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径。
3.6 mybatis是怎么实现分页的,内部原理是什么?
pageHelper 内部拦截器 sql向数据库发起查询的时候,进行拦截,同时加入对应的limit语句
3.7 mybatis有什么优点?
答:
1)MyBatis 把 sql 语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的 维护带来了很大便利。
2)MyBatis 封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean 对象, 大大简化了 Java 数据库编程的重复工作。
3)因为 MyBatis 需要程序员自己去编写 sql 语句,程序员可以结合数据库自身的特点灵活 控制 sql 语句,因此能够实现比 Hibernate 等全自动 orm 框架更高的查询效率,能够完成复 杂查询。