什么是Spring?
Spring是一个轻量级Java开发框架,最早由Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/Java EE ful-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础加构支持。
Spring负责基础加构,因此Java开发者可以专注于应用程序的开发。
Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。
Spring 可以最很多事情,它为企业级开发提供了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入 (Dependency injection,DI)和面向切面编程(Aspect-oriented programing,AOP)。
为了降低Java开发的复杂性,Spring采取了以下4种关键策略
- 基于POJO的轻量级和最小侵入性编程
- 通过依赖注入和面向接口实现松耦合
- 基于切面和惯例进行声明式编程
- 通过切面和模板减少样板式代码
Spring框架的设计目标,设计理念,和核心是什么?
Spring设计目标: Spring为开发者提供一个一站式轻量级应用开发平台
Spring设计理念: 在JavaEE开发中,支持POJO和JavaBean开发方式,使应用面向接口开发,充分支持OOP设计方法;Spring通过Ioc容器实现对象耦合关系的管理,并实现依赖反转,将对象之间的依赖关系交给Ioc容器,实现解耦;
Spring框架的核心: Ioc容器和Aop模块。通过AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件
Spring的优缺点是什么?
优点:
方便解耦,简化开发
spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给Spring管理。
AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
方便程序的测试
Spring对Junit4的支持,可以通过注解方便的测试Spring程序。
方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持(如:Struts,Hibernate,Mybatis)
降低JavaEE API的使用难度
Spring对JavaEE开发中非常难用的一些API(JDBC,JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。
缺点:
- Spring明明是一个轻量级的框架,却给人感觉大而全
- Spring依赖反射,反射影响性能
- 使用门槛高,入门Spring需要较长时间
Spring 有哪些应用场景
应用场景:JavaEE企业级应用开发,包括SSH、SSM等
Spring价值:
- Spring是非侵入式的框架,目标是使应用程序代码对框架依赖最小化
- Spring提供一个一致的编程模型,使应用直接使用POJO开发,与运行环境隔离开来
- Spring推动应用设计风格向面向对象和面向接口开发转变、提高了代码的重用性和可测试性;
Spring 由哪些模块组成?
Spring总共大约由20个模块,由1300多个不同的文件构成。而这些组件被分别整合在 核心容器(Core)、AOP、设备支持、数据访问与集成、Web、消息、Test等6个模块中。以下是Spring 5的模块结构图:
- Spring core:提供了框架的基本组成部分,包括控制反转IOC和依赖注入DI的功能
- Spring beans:提供了BeanFactory,是工厂模式的一个经典实现,spring将管理对象称为Bean
- Spring context:构建于core封装包基础上的context封装包,提供了一种框架式的对象访问方法
- Spring jdbc:提供了一个JDBC的抽象层,消除了繁琐的JDBC编码和数据库厂商特有的错误代码接续,用于简化JDBC
- Spring aop:提供了面向切面的编程实现,让你开源自定义拦截器、切点等。
- Spring Web:提供了针对Web开发的集成特性,例如文件上传,利用servlet listeners 进行ioc容器初始化和针对Web 的ApplicationContext
- Spring test: 主要为测试提供支持的,支持使用JUnit或者TestNg对Spring组件单元测试和集成测试。
Spring 框架中都用到了哪些设计模式?
- 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
- 单例模式:Bean默认为单例模式
- 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术
- 模板方法:用来解决代码重复的问题,比如:RestTemplate,Jmstemplate
- 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被动更新,如Spring中listener的实现-ApplicationListener
详细讲解一下核心容器(Spring context应用上下文)模块
这是基本的Spring模块,提供了Spring框架的基础功能,BeanFactory 是任何以spring为基础的应用的核心。Spring框架建立在此模块之上,它使Spring成为一个容器。
bean工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从真正的应用代码中分离。
Spring 应用程序由哪些不同组件?
- 接口-定义功能
- Bean类-它包含属性,setter 和 getter 方法,函数等
- Bean配置文件- 包含类的信息以继如何配置它们
- Spring 面向切面编程-提供面向切面编程的功能
- 用户程序-它使用接口
使用Spring有哪些方式?
- 作为一个成熟的Spring Web 应用程序
- 作为第三方Web 框架,使用Spring Frameworks中间层
- 作为企业级Java Bean,它开源包装现有的POJO
- 用于远程使用。
什么是Spring IOC容器
控制反转即为IOC ,它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
Spring IOC负责创建对象,管理对象(通过依赖注入DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
控制反转有什么用?
- 管理对象的创建和依赖关系的维护。对象的创建并不是一件简单的事,在对象关系比较复杂时,如果依赖关系需要程序员来维护的话,那是相当头疼的。
- 解耦,由容器去维护具体的对象
- 托管了类的产生过程。比如我们需要在的产生过程中做一些处理,最直接的例子就是代理,如果有容器程序开源把这部分处理交给容器,应用程序则无序去关系类是如何完成代理的。
IOC的优点是什么?
- IOC或依赖注入把应用的代码量讲到最低
- 它使应用容易测试,单元测试不再需要单例和JNDI查找机制
- 最小的代价和最小的侵入性使松散耦合得以实现。
- IOC容器支持加载服务时的饿汉式初始化和懒汉式加载
Spring IOC的实现机制
IOC实现原理就是工厂模式加反射机制
使用@Autowired注解自动装配的过程是怎么样的?
使用@Autowired注解来自动装配知道的bean。在使用@Autowired注解之前需要咋Spring配置文件进行配置,<context:annotation-config>
在启动Spring IOC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到了@Autowired、@Resource、@Inject时,就会在Ioc容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:
如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
如果查询的结果不止一个,那么@Autowired会根据名字来查找
如果上述查找的结果为空,那么会抛出异常。解决方法:使用required=false
@Component @Controller @Repository @Service 有何区别?
@Component:这将Java类标记为bean,它时任何Spring管理组件的通用构造形式。Spring的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。
@Controller:这将一个类标记为Spring Web Mvc控制器。标有它的Bean会自动导入到Ioc容器中
@Service:此注解时组件注解的特化。它不会对@Component注解提供任何其他行为。您可以在服务层中使用@Service而不是@Component,因为它以更好的昂是指定了意图。
@Repository:这个注解时具有类似用途和功能的@Component注解的特化。它为DAO提供了额外的好处,它将DAO导入IOc容器,并使未经检查的异常有资格转换为Sprig DataAccessException。
@Autowired和@Resource之间的区别?
- @Autowired 默认时按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它的required属性为false)
- @Resource默认时按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入
@RequestMapping 注解有什么用?
用于将特定Http请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可用于两个级别:
类级别:映射请求的URL
方法级别:映射URL以继HTTP请求方法
解释对象/关系映射集成模块
Spring通过提供ORM模块,支持我们直接在JDBC之上使用一个对象/关系映射(ORM)工具,Spring支持集成主流的ORM框架,如Hibernate、JDO和iBatis。Spring的事务管理同样支持以上所有ORM框架及JDBC
Spring DAO有什么用?
Spring DAO(数据访问对象)使得JDBC、Hibernate 或 JDO 这样的数据访问技术更容易以一种统一的方式工作。这使得用户容易在持久性技术之间切换。它还允许您在编写代码时,无序考虑捕获每种技术不同的异常。
Spring支持的事务管理类型,Spring事务实现方式有哪些?
Spring 支持两种类型的事务管理:
编程式事务管理: 这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
声明式事务管理: 这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。
Spring 事务的实现方式和实现原理
Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,Spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
说一下Spring的事务隔离?
Spring有五大隔离级别,默认值为ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:
- ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
- ISOLATION_READ_UNCOMMITTED:未提交读,最低隔离级别,事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);
- ISOLATION_READ_COMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL Server的默认级别;
- ISOLATION_REPEATABLE_READ:可重复读,保证多次读取同一个数据时,其值都和事务开始的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别;
- ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读;
**脏读:**表示一个事务能够读取另一个事务中还未提交的数据。比如:某个事务尝试插入记录A,此时该事务还为提交,然后另一个事务尝试读取到了记录A
**不可重复读:**是指在一个事务内,多次读同一个数据。
**幻读:**指同一个事务内多次查询返回的结果集不一样。比如同一个事务A第一次查询时有n条记录,但是第二次同等条件下查询却有n+1条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。
Spring框架的事务管理有哪些优点?
- 为不同的事务API如JTA,JDBC,Hibernate,JPA和JDO,提供一个不变的编程模式
- 为编程式事务管理提供了一套简单的API而不是一些复杂的事务API
- 支持声明式事务管理
- 和Spring各种数据访问抽象层很好的集成
你更倾向用那种事务管理类型?
大多数Spring框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要由于编程式事务管理,虽然比编程式事务管理少了一点灵活性。唯一不足地方是,最细粒度只能作用到方法级别,无法左到像编程式事务那样可以作用到代码块级别。