1、为什么要使用 spring?
方便解耦,便于开发(Spring就是一个大工厂,可以将所有对象的创建和依赖关系维护都交给spring管理)
- spring支持aop编程(spring提供面向切面编程,可以很方便的实现对程序进行权限拦截和运行监控等功能)
- 声明式事务的支持(通过配置就完成对事务的支持,不需要手动编程)
- 方便程序的测试,spring 对junit4支持,可以通过注解方便的测试spring 程序
- 方便集成各种优秀的框架()
- 降低javaEE API的使用难度(Spring 对javaEE开发中非常难用的一些API 例如JDBC,javaMail,远程调用等,都提供了封装,是这些API应用难度大大降低)
2、解释一下什么是 aop?
面向切面编程
3、解释一下什么是 ioc?
控制反转又叫依赖注入(DI)
4、spring 有哪些主要模块?
原文链接:https://blog.csdn.net/qq_41247433/article/details/79441088
Spring框架主要有哪些模块
主要七大模块介绍
- Spring AOP 面相切面编程
- Spring ORM Hibernate|mybatis|JDO
- Spring Core 提供bean工厂 IOC
- Spring Dao JDBC支持
- Spring Context 提供了关于UI支持,邮件支持等
- Spring Web 提供了web的一些工具类的支持
- Spring MVC 提供了web mvc , webviews , jsp ,pdf ,export
附带版本 参考
1. Spring Core:
Core封装包是框架的最基础部分,提供IOC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
2.Spring Context:
构建于Core封装包基础上的 Context封装包,提供了一种框架式的对象访问方法,有些象JNDI注册器。Context封装包的特性得自于Beans封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和Context的透明创建,比如说通过Servlet容器。
3.Spring DAO:
DAO (Data Access Object)提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 并且,JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs(plain old Java objects)都适用。
4.Spring ORM:
ORM 封装包提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、JDO、Hibernate 和 iBatis 。利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。
5.Spring AOP:
Spring的 AOP 封装包提供了符合AOP Alliance规范的面向方面的编程实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中。
6.Spring Web:
Spring中的 Web 包提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servlet listeners进行IOC容器初始化和针对Web的ApplicationContext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。
7.Spring Web MVC:
Spring中的MVC封装包提供了Web应用的Model-View-Controller(MVC)实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和Web Form之间。并且,还可以借助Spring框架的其他特性。
8、spring 常用的注入方式有哪些?
常用的有三种方式:
- setter方法注入
- 构造器注入
- 使用注解注入
9、spring 中的 bean 是线程安全的吗?
源文链接:https://blog.csdn.net/qq_29645505/article/details/88432001
Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策略,因此可以说Spring容器中的Bean本身不具备线程安全的特性,但是具体还是要结合具体scope的Bean去研究。
Spring 的 bean 作用域(scope)类型
- singleton:单例,默认作用域。
- prototype:原型,每次创建一个新对象。
- request:请求,每次Http请求创建一个新对象,适用于WebApplicationContext环境下。
- session:会话,同一个会话共享一个实例,不同会话使用不用的实例。
- global-session,全局会话,所有会话共享一个实例。
线程安全这个问题,要从单例与原型Bean分别进行说明。
原型Bean:
对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,自然是不会有线程安全的问题。
单例Bean:
对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。
如果单例Bean,是一个无状态Bean,也就是线程中的操作,不会对Bean的成员执行查询以外的操作(评论区补充:无状态bean:即调用bean的方法不会使bean的字段属性发生改变,),那么这个单例Bean是线程安全的。比如Spring mvc 的 Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。
对于有状态的bean,Spring官方提供的bean,一般提供了通过ThreadLocal去解决线程安全的方法,比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等。
使用ThreadLocal的好处:
使得多线程场景下,多个线程对这个单例Bean的成员变量并不存在资源的竞争,因为ThreadLocal为每个线程保存线程私有的数据。这是一种以空间换时间的方式。当然也可以通过加锁的方法来解决线程安全,这种以时间换空间的场景在高并发场景下显然是不实际的。
10、spring 支持几种 bean 的作用域?
问题9中提到,spring的 Bean 支持五种作用域。下面我们细说:
原文链接:https://blog.csdn.net/u011468990/article/details/49995865
当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域:
- singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例;
- prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例;
- request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效;
- session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效;
- globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效;
其中比较常用的是 singleton 和 prototype 两种作用域。对于 singleton 作用域的 Bean,每次请求该 Bean 都将获得相同的实例。容器负责跟踪 Bean 实例的状态,负责维护 Bean 实例的生命周期行为;如果一个 Bean 被设置成 prototype 作用域,程序每次请求该 id 的 Bean,Spring 都会新建一个 Bean 实例,然后返回给程序。在这种情况下,Spring 容器仅仅使用new 关键字创建Bean 实例,一旦创建成功,容器不在跟踪实例,也不会维护 Bean 实例的状态。
如果不指定 Bean 的作用域,Spring 默认使用 singleton 作用域。Java 在创建J ava 实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype 作用域 Bean 的创建、销毁代价比较大。而 singleton作用域的 Bean 实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将 Bean 被设置成 prototype 作用域。
11、spring 自动装配 bean 有哪些方式?
spring 自动装配的方式共有如下五种:
- no:默认方式,手动装配方式,需要通过ref设定bean的依赖关系
- byName:根据bean的名字进行装配,当一个bean的名称和其他bean的属性一致,则自动装配
- byType:根据bean的类型进行装配,当一个bean的属性类型与其他bean的属性的数据类型一致,则自动装配
- constructor:根据构造器进行装配,与 byType 类似,如果bean的构造器有与其他bean类型相同的属性,则进行自动装配
- autodetect:如果有默认构造器,则以constructor方式进行装配,否则以byType方式进行装配
原文链接:https://blog.csdn.net/qq_37908493/article/details/88670246
参考博文:https://blog.csdn.net/qq_34598667/article/details/83317377
12、spring 事务实现方式有哪些?
spring 实现事物管理有如下四种方式:
- 编程式事务管理对基于 POJO 的应用来说是唯一选择。我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。
- 基于 TransactionProxyFactoryBean的声明式事务管理
- 基于 @Transactional 的声明式事务管理
- 基于Aspectj AOP配置事务
详见博文:https://blog.csdn.net/CHINACR07/article/details/78817449,非常之详细。
13、说一下 spring 的事务隔离?
原文:http://www.mamicode.com/info-detail-2330326.html,事物的四种特性,五种隔离级别,七种传播行为。
spring 中的五种事务隔离级别:
- DEFAULT:这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。
- 未提交读(read uncommited):脏读,不可重复读,虚读都有可能发生 。
- 已提交读 (read commited):避免脏读。但是不可重复读和虚读有可能发生 。
- 可重复读 (repeatable read):避免脏读和不可重复读.但是虚读有可能发生。
- 串行化的 (serializable):避免以上所有读问题。
Mysql 默认:可重复读 ,Oracle 默认:读已提交
14、说一下 spring mvc 运行流程?
原文:https://blog.csdn.net/qq_32575047/article/details/80416015
spring mvc 的运行流程大致可以分为5个步骤:
- 捕获:用户向服务器发送请求,请求被 Spring 前端控制 Servelt DispatcherServlet 捕获;
- 查找Handler:DispatcherServlet对请求 URL进行解析,得到请求资源标识符(URI)。然后根据该 URI,调用 HandlerMapping获得该Handler配置的所有相关的对象(包括 Handler对象以及 Handler对象对应的拦截器),最后以 HandlerExecutionChain对象的形式返回;
- 执行Handler:DispatcherServlet 根据获得的 Handler,选择一个合适的 HandlerAdapter。 提取Request 中的模型数据,填充 Handler 入参,开始执行 Handler(Controller), Handler执行完成后,向 DispatcherServlet 返回一个 ModelAndView 对象;
- 选择ViewResolver:DispatcherServlet 根据返回的 ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到 Spring 容器中的 ViewResolver)
- 渲染返回:通过 ViewResolver 结合 Model 和 View,来渲染视图,DispatcherServlet 将渲染结果返回给客户端。
这些过程都是以DispatcherServlet为中轴线进行的。如下图:
15、spring mvc 有哪些组件?
原文链接:https://blog.csdn.net/hustwht/article/details/52280968
Spring MVC的组件主要包括:
- 前端控制器组件(DispatcherServlet)
- 处理器组件(Controller)
- 处理器映射器组件(HandlerMapping)
- 处理器适配器组件(HandlerAdapter)
- 拦截器组件(HandlerInterceptor)
- 视图解析器组件(ViewResolver)
- 视图组件(View)
- 数据转换组件(DataBinder)
- 消息转换器组件(HttpMessageConverter)
16、@RequestMapping 的作用是什么?
原文:https://blog.csdn.net/qq_29645505/article/details/89528784
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或者方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
@RequestMapping注解有六个属性,下面进行详细的说明。
1.value, method
value:指定请求的实际地址,指定的地址可以是URI Template模式。
method:指定请求的method类型,GET、POST、PUT、DELETE等。
2.consumes, produces
consumes:指定处理请求的提交内容类型(Content-Type),例如application/json,text/html。
produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。
3.params, headers
params:指定request中必须包含某些参数值才让该方法处理。
headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
17、@Autowired 的作用是什么?
@Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。在使用@Autowired之前,我们对一个bean配置起属性时,是这用用的:
<property name="属性名" value=" 属性值"/>
通过这种方式来,配置比较繁琐,而且代码比较多。在Spring 2.5 引入了 @Autowired 注释,通过@Autowired自动装配方式,从IoC容器中去查找到,并返回给该属性。