1.Spring的优缺点?你为什么使用Spring?
spring因为本身不大,所需性能开销也非常小,能够满足开发一个web程序所需要的所有技术,spring属于非侵入式,代码污染极低,它的低耦合的设计也使得项目后期维护起来非常方便,它的事务管理也很简洁方便,面向切面的管理模式管理起来统一,整洁,对主流的框架页提供了很好的集成,比如hibernate,struts2,mybatis等等,spring的高度可开放性,并不强制依赖于spring,开发者可以自由选择spring部分或全部。
2、spring中的Bean的生命周期和作用域:
作用域:
singleton 单例(默认) 在IOC容器中,这个Bean只有一个对象
Prototype 原型 每次访问都会生成一个新的Bean实例
request
session
global session
通过使用xml中的scope属性来配置,或者使用@Scope注解
生命周期:实例化(调用构造方法)》》初始化(调用init-method指定的方法)》》调用》》销毁(调用destory-method指定的方法)
3、Spring是什么?
spring是一个轻量级,一站式,非侵入式的开源框架
轻量级:spring本身不大,所需要的性能开销也非常小
一站式:spring提供构建一个web程序所需要的所有技术
非侵入式:解耦,低耦合的设计
4、Spring的核心是什么?
spring 的核心就是
IOC :inversion of control 控制反转
DI :depencdy injection 依赖注入
总结:IOC和DI是同一个事务的不同角度的描述,站在调用者的角度,它感觉原来的控制权转移到了IOC容器,称之为控制反转,站在IOC的角度,它需要将被调用者和调用者之间的关系进行装配,讲调用者和被调用者之间的依赖进行管理,这个过程就叫DI 依赖注入。
5、什么是IOC?IOC有什么好处?为什么使用IOC?
IOC :inversion of control 控制反转
定义:反转了创建对象的控制权,控制权从调用者手中转移到了IOC容器
好处:调用者只需要声明被调用,无需自己去实例化,这就直接讲调用者和被调用者之间的耦合度砍断,通过IOC容器,来装配两者之间的关系
6、什么是DI?依赖注入的几种方式?最常用的是什么?为什么?
DI :depencdy injection 依赖注入
定义:注入了bean和bean之间的依赖关系,把被调用者注入给调用者
注入方式:
属性注入(set注入、设值注入):通过调用set方法来注入,需要提供一个set方法
勾走注入:通过对应的构造方法来注入,需要提供对应的构造方法
7、什么是AOP?
AOP Aspect Oriendted Pragram 面向切面编程,是面向对象编程的一个补充。它又叫面向横切面编程。
何为面向切面:将系统中的通用模块抽取出来,放入到切面中,在程序运行过程中,动态的切入进去
8、AOP常见的术语?为什么使用AOP?
切面Aspect
将系统中的通用功能抽取出来,放在一个类中,该类就称之为切面类
通用功能所在的类就称之为切面类
连接点JoinPoint
单个的切入点,就叫连接点
切入点Pointcut
多个连接点的集合,称之为切入点
目标对象Target
通知Advice
也叫:增强(Ehance)
将目标对象拦截下来,做前置处理和后置处理。这些处理,就叫通知(增强)
代理Proxy
织入Wear
将前后通知加入到目标对象的前后的过程,就称之为织入
AOP的示例代码:
编写切面类:
package com.psfd.spring;
public class LogginAspect {
public void before() {
System.out.println("开始执行");
}
public void after() {
System.out.println("执行完毕");
}
}
配置AOP的切入:
<bean id="logginAspect" class="com.psfd.spring.LogginAspect"></bean>
<aop:config>
<aop:pointcut id="loginPointcut"
expression="execution(* com.psfd.spring.service..*.*(..))" />
<aop:aspect ref="logginAspect">
<aop:before method="before" pointcut-ref="loginPointcut"/>
<aop:after method="after" pointcut-ref="loginPointcut"/>
</aop:aspect>
</aop:config>
9、AOP的优缺点?
有点:最大好处就是去重,解耦,把通用模块统一管理
缺点就是编程变得稍微复杂了点,代码量增多,性能上面有点下降
10、Spring的常用注解?各自有什么作用?
@RequestMapping 是一个用来处理请求地址映射的注解(将请求映射到对应的控制器方法中),可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
它的参数:
value:指定请求的实际url,用在类上面就是命名空间
method :指定请求的method 类型,如: get,post,put,delete等
params:指定request中必须包含某些参数值,符合才让该方法处理
consumes:指定处理请求的提交内容类型
produces:指定返回的内容类型,仅当request请求头中的Accept类型中包含该指定类型才返回
@RequestParam 用于将请求参数区数据映射到功能处理方法的参数上
它的参数:
value : 参数名,指定页面参数名
required:是否必须,默认是ture,表示请求中一定要有相应的参数,否则将抛出异常
defaultValue:默认值,表示如果请求中没有同名参数时的默认值,设置该参数时,自动将required设为false
@PathVariable 用于将请求url中的模板变量映射到功能处理方法的参数上
比如:
@RequestMapping(value="/users/{userId}/topics/{topicId}")public String test(
@PathVariable(value="userId") int userId,
@PathVariable(value="topicId") int topicId)
如请求的URL为“控制器URL/users/123/topics/456”,则自动将URL中模板变量{userId}和{topicId}绑定到通 过@PathVariable注解的同名参数上,即入参后userId=123、topicId=456。
@Controller 修饰Controller
@Service 修饰Service
@Repository 修饰dao
@Component 当一个类你不确定他是Controller还是Service还是Dao,你就是用该注解
@Resource 先按照名称注入,如果找不到对应的名称,就按类型注入
@Autowired 按照类型注入
@RequestMapping 请求的映射,可以使用在类上,也可以使用在方法上
@ResponseBody 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。比如返回json,xml格式的数据
@RequestParam 参数也页面数据的对应
@PathVariable 路径变量
@Transactional 事务管理的注解
11、spring的事务管理:
1.什么叫事务?
将一组操作捆绑起来,形成一个不可分割的操作单元,要么全部失败,要么全部成功
2.事务的四大特性:
原子性 atonmictiy 整体是一个操作单元,要么都做,要么都不做
隔离性 lsolation 每个事务内部的操作以及使用的数据对其他并发事务是隔离的,并发执行的事务之间互相不干扰
一致性 consistency 整个事务提交,数据库的状态必须保持一致,要么全部成功,要么全部失败
持久性 指事务一旦提交成功,它对数据库的改变是永久性的
3. 事务的隔离级别:
read_uncommitted 级别最低,允许脏读,不可重复读,幻象读
read_committed 禁止脏读,允许不可重复读和幻象读,orcale 默认
repeatable_read 禁止脏读,不可重复读,允许幻象读 mysql 默认
serialzable 级别最高,全部禁止,非常严重的性能问题
4. 事务的传播行为:
定义:事务与事务之间的传递。
required :当前方法必须在事务中运行,如果当前已经有事务,加入当前事务中
requires_new: 方法必须在事务钟运行,而且一定要是新事物,如果当前已经存在事务,挂起当前事务,开启一个新的事务
supports: 如果当前存在事务,则加入事务;如果当前没有事务,则以非事务的方式继续运行。
not_supported: 以非事务方式运行,如果当前存在事务,则把当前事务挂起,
never: 以非事务的方式运行,如果当前存在事务,则抛出异常。
mandatory: 如果当前存在事务,则加入该事务,如果当前没有事务,则抛出异常
声明一个事务管理设置代码:
<!-- 定义一个事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
隔离级别,传播行为的设置代码:
<!-- 配置事务的相关属性 -->
<tx:advice id="txAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"
isolation="DEFAULT" />
</tx:attributes>
</tx:advice>
事务指定切入代码:
<!-- 在程序指定位置切入 -->
<aop:config>
<aop:pointcut id="interceptorPointCuts"
expression="execution(* com.psfd.spring.service..*.*(..))" />
<aop:advisor advice-ref="txAdvice"
pointcut-ref="interceptorPointCuts" />
</aop:config>
12、Spring 的事务声明方式:
编程式事务:spring 提供了事务管理的api,开发人员在程序中,自己写代码来控制事务,这是传统的事务管理方式
优点:控制粒度非常细,随便控制,可以细化到控制某一行代码
缺点:会导致事务管理的代码在程序中遍地都是,大量重复,并且业务功能的代码与事务管理的代码混合在一起。
声明式事务:spring 的声明式事务管理在底层式建立在AOP的基础之上的,其本质式对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
优点:声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码钟参杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或者通过等价的基于标注的方式),便可以将事务规则应用到业务逻辑中,因为事务管理本事就是一个典型的横切逻辑,正是AOP的用武之地。
如果开发中使用声明式事务,不仅因为其简单,更主要是因为这样使得纯业务代码不被污染,极大方便后期的代码维护。
缺点:控制的粒度一般只能细化到方法级别。如果需要更进一步细化,可以将需要单独做事务控制的代码抽成方法
13、代理模式
什么是代理模式:
为一个对象提供一种代理,以控制对这个对象的访问和操作
静态代理:自己写代理的方式就叫静态代理
动态代理:JDK的动态代理
1.提供了一个实现InvocationHandler接口的类,重写其invoke方法,在该方法中通过反射调用目标对象的方法。
2.通过调用java.lang.reflect.proxy类的newProxyInstance方法生成一个代理对象。
3.调用即可
代理模式的优点:
职责清晰,业务逻辑处理类,只专注于处理自己的逻辑,其他的不关注,解耦合,提高了代码的扩展性与可维护性
缺点:代码变得复杂,性能略微下降
14.SpringMVC的流程
前提:在SpringMVC中,看到Handler就是Controller。
1、客户端发送一个请求,如果符合指定后缀,会进入到SpringMVC核心控制器。
2、核心控制器解析请求的URL,获取请求的名称。然后查找是否有对应的Controller来处理这个请求。
如何查找?查找HandlerMappping(是服务器启动的时候,扫描并解析注解,生成一个map集合。
其中key:注解中给定的请求名称,value:具体的方法对象)
如果找到,准备调用,如果没有,返回404.
3、收集并且封装页面发送过来的数据
①、收集数据
②、自动数据类型转换(基本数据类型)
③、封装数据为javaBean的对象。
4、将数据传入到Controller的方法中,执行方法
5、Controller执行完成后,返回ModelAndView的对象。
ModelAndView是包含了请求的跳转信息,以及需要响应给客户端的数据。
6、视图解析器(ViewResolver)解析ModelAndView,提取其中的数据信息和页面信息。
7、渲染视图,将视图信息和数据信息,解析出来,生成对应的静态HTML文本
浏览器只认识HTML。不认识:jsp等动态页面。
8、将html文本,响应给浏览器,显示出来。