1、Spring Bean的作用域之间有什么区别
在Spring中,可以在<bean>元素的scope属性里设置bean的作用域,以决定这个bean是单实例的还是多实例的。
默认情况下,Spring只为每个IOC容器里声明的bean创建唯一个实例,整个IOC容器范围内都能共享该实例:所有后续的getBean()调用和bean引用都将返回这个唯一的bean实例。该作用域被称为singleton,它是所有bean的默认作用域。
类别 | 说明 |
---|---|
singleton | 在SpringIOC容器中仅存在一个Bean实例,Bean以单实例的方式存在 |
prototype | 每次调用getBean()时都会返回一个新的实例 |
request | 每次Http请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 |
session | 同一个Http Session共享一个Bean,不同的HTTP Session使用不同的Bean。该作用域仅适用于WebApplicationContext环境。 |
2、请简单介绍Spring支持的常用数据库事务传播属性和事务隔离级别
2.1 事务的传播行为
当事务被另一个事务方法调用时,必须指定事务该如何传播。即一个方法运行在了一个开启了事务的方法中时,当前方法是使用原来的事务还是开启一个新的事务。
事务传播属性可以在@Transactional注解的propagation属性中定义。
传播属性 | 描述 |
---|---|
REQUIRED(默认) | 如果有事务在运行当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行。 |
REQUIRES_NEW | 当前方法必须启动新事务,并在它自己的事务内运行,如果有事务正在运行,应该将它挂起。 |
SUPPORTS | 如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务内。 |
NOT_SUPPORTED | 当前方法不应该运行在事务中,如果有运行的事务,将它挂起。 |
MANDATORY | 当前的方法必须运行在事务内部,如果没有运行的事务,就抛出异常。 |
NEVER | 当前方法不应该运行在事务中,如果有运行的事务,就抛出异常。 |
NESTED | 如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新的事务,并在它自己的事务内运行。 |
2.2 事务的隔离级别
2.2.1 数据库事务并发问题
- 脏读:当前事务读取到了其他事务尚未提交(最后回滚了)的值。
- 不可重复读:当前事务读取了A值,其他的事务将A值修改了,当前事务再次读取A值与前一次读取的值不同(针对update和delete)
- 幻读:当前事务根据某条件读取了A表的部分数据,另一事务修改了另外的部分数据使之符合了该条件,或添加了多条符合该条件的数据,使当前事务再次根据该条件读取时发现多了数据(针对insert)
2.2.2 隔离级别
隔离级别:一个事务与其他事务隔离的程度
-
读未提交:READ UNCOMMITTED
允许Transaction01读取Transaction02未提交的修改。
-
读已提交:READ COMMITTED
允许Transaction01读取Transaction02已提交的修改。
-
可重复度:REPEATABLE READ
确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其他事务对这个字段进行更新。
-
串行化:SERIALIZABLE
确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其他事务对这个表进行添加、更新、删除操作。可以避免发生任何并发问题,但性能十分低下。
Oracle只支持读已提交(默认)和串行化,Mysql全支持,默认为可重复读。
隔离级别可以在@Transactional的isolation属性来设置。
3、SpringMVC中如何解决GET/POST请求中文乱码问题
3.1解决POST请求乱码
3.1.1 第一种方法:web.xml配置
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.1.2 第二种方法:创建filter类
public class EncoidingFilter implements Filter {
private String encoding="";
@Override
public void destroy() { }
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig config) throws ServletException {
this.encoding = config.getInitParameter("encoding");//读取web.xml
}
}
<filter>
<filter-name>EncoidingFilter</filter-name>
<filter-class>com.example.filter.EncoidingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncoidingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.2 解决GET请求乱码(tomcat8.0之后都默认设置了)
在tomcat服务器的server.xml中,找到第一个Connector标签,添加属性URIEncoding="UTF-8"
保存。
4、简单谈一下SpringMVC的工作流程
4.1 处理模型数据的方式
-
将返回值设置为ModelAndView
-
注解
@RequestMaping(/test)
-
创建ModelAndView对象
ModelAndView mav = new ModelAndView();
-
设置模型参数
mav.addObject("user","admin");
-
设置视图
mav.setViewName("success");
-
返回该对象
return mav;
-
-
方法的返回值仍时String类型,在方法的入参中传入Map、Model或ModelMap
两种方法,SpringMVC都会转换成为一个ModelAndView对象
4.2 运行流程
- 前端发送请求至SpringMVC,由前端控制器DispatcherServlet(中央控制器)来拦截该请求
- DispatcherServlet会调用HandlerMapping(处理器映射器)去找到处理器
- 处理器映射器找到具体的处理器,会生成一个HandlerExecutionChain对象(包含Handlerintercepter处理器拦截器、Handler处理器对象)返回给DispatcherServlet
- DispatcherServlet调用HandlerAdapter处理器适配器(通过处理器适配器调用具体的处理器)
- HandlerAdapter经过适配调用具体的Handler处理器(Controller,也叫后端控制器)
- Controller执行完成返回ModelAndView
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet(无论是否存在异常,其中包含了模型数据和视图)
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器(InternalResourceViewResolver)
- ViewReslover解析后返回具体View
- DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)
- DispatcherServlet响应用户
几个组件:
-
前端控制器(DispatcherServlet):接收请求,响应结果
-
处理器映射器(HandlerMapping):根据URL去查找处理器
-
处理器适配器(HandlerAdapter):会把处理器包装成适配器,这样就可以支持多种类型的处理器
-
处理器(Handler):(即Controller需要程序员去写代码处理逻辑的)
-
视图解析器(ViewResovler):进行视图解析,多返回的字符串,进行处理,可以解析成对应的页面
5、 MyBatis中实体类的属性名和表中的字段名不一致怎么办
5.1 写sql语句的时候起别名
5.2 在Mybatis的全局配置文件中开启驼峰命名规则
<settings>
<setting name="mapUpdaterscoreToCamelCase" value="true"/>
</settings>
5.3 Mapper映射文件中使用resultMap来自定义映射规则
<!-- 自定义映射 -->
<!-- type为你的实体类,id为唯一标识 -->
<resultMap type="com.example.mybatis.entities.User" id="userMap">
<!-- 映射主键 -->
<id column="id" property="id"/>
<!-- 映射其他列 -->
<result column="user_name" property="userName"/>
</resultMap>
<select id="getUserById" resultMap="userMap">
select * from user where id = #{id}
</select>