什么是Spring?
Spring 是一个开源应用框架,旨在降低应用程序开发的复杂度。
它是轻量级、松散耦合的。
它具有分层体系结构,允许用户选择组件,同时还为 J2EE 应用程序开发提供了一个有凝聚力的框架。
Spring还可以完成技术的整合,该框架提供了IOC和AOP的机制,基于这些特性,可以降低组件之间的耦合度,
便于系统组件的维护,扩展和替换。 主要利用spring容器管理我们程序中的controller、service、dao组件,通过容器的IOC和AOP机制,降低 组件之间的联系,利用IOC特性降低service和dao之间的关联,利用aop进行事务等共通部分的处理。
什么是Spring IOC?
IOC(Inverse of Controller):控制反转
- 控制:对象的创建、初始化、销毁和对象之间关系的指定
- 反转:将控制的逻辑交给第三方框架或者容器负责,当两个组件之间的关系发生改变时,只需要修改框架或者容器的配置
Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供
什么是依赖注入?
在依赖注入中,您不必创建对象,但必须描述如何创建它们。您不是直接在代码中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务。由 IOC 容器将它们装配在一起。
什么是Spring AOP?描述其应用场景(最少3个)
AOP(Aspect-Oriented Programming), 即 面向切面编程, 它与 OOP( Object-Oriented Programming, 面向对象编程) 相辅相成, 提供了与 OOP 不同的抽象软件结构的视角. 在 OOP 中, 我们以类(class)作为我们的基本单元, 而 AOP 中的基本单元是 Aspect(切面)
AOP应用场景:
- Authentication 权限
- Caching 缓存
- Transactions 事务
- Context passing 内容传递
- Error handling 错误处理
- Lazy loading 懒加载
- Debugging 调试
- logging, tracing, profiling and monitoring 记录跟踪 优化 校准
AOP的通知有几个,分别是什么
1. 前置通知(Before):方面组件在目标组件之前执行
2. 后置通知(After):方面组件在目标组件之后执行,目标组件方法没有抛出异常才会执行方面组件
3. 最终通知(After-returning ):方面组件在目标组件之后执行,目标组件不管是否发生异常都会执行
方面组件
4. 异常通知(After-throwing):方面组件在目标组件抛出异常之后执行
5. 环绕通知(Around):方面组件在目标组件之前和之后执行
什么是 Spring Bean?
它们是构成用户应用程序主干的对象。
Bean 由 Spring IoC 容器管理。
它们由 Spring IoC 容器实例化,配置,装配和管理。
Bean 是基于用户提供给容器的配置元数据创建。
SpringBean自动装配有哪些方式
Spring 容器能够自动装配 bean。也就是说,可以通过检查 BeanFactory 的内容让 Spring 自动解析 bean 的协作。
自动装配的不同模式:
no - 这是默认设置,表示没有自动装配。应使用显式 bean 引用进行装配。
byName - 它根据 bean 的名称注入对象依赖项。它匹配并装配其属性与 XML 文件中由相同名称定义的 bean。
byType - 它根据类型注入对象依赖项。如果属性的类型与 XML 文件中的一个 bean 名称匹配,则匹配并装配属性。
构造函数 - 它通过调用类的构造函数来注入依赖项。它有大量的参数。
autodetect - 首先容器尝试通过构造函数使用 autowire 装配,如果不能,则尝试通过 byType 自动装配。
自动装配有什么局限
覆盖的可能性 - 您始终可以使用
和 设置指定依赖项,这将覆盖自动装配。 基本元数据类型 - 简单属性(如原数据类型,字符串和类)无法自动装配。
令人困惑的性质 - 总是喜欢使用明确的装配,因为自动装配不太精确。
描述Spring Bean的作用域 scope?
Spring框架支持以下五种bean的作用域:
- singleton : 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。
- prototype:每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。
- request:每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring
WebApplicationContext环境。
- session:同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。
- application:限定一个Bean的作用域为`ServletContext`的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。
Spring Bean 注入有几种方式?
- setter注入
- 构造方法注入
- 工厂方法注入
SpringBean 生命周期?
1通过构造器或工厂方法创建 Bean 实例
2为 Bean 的属性设置值和对其他 Bean 的引用
3调用 Bean 的初始化方法
4使用Bean
5当容器关闭时 close(), 调用 Bean 的销毁方法
在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法.
假如 增加Bean后置处理器, 需要实现BeanFactoryPostProcessor接口. 在初始化方法被调用前后, 它定义了两个方法,一个在bean初始化之前,一个在bean初始化之后。
Spring框架中 用到了哪些设计模式?(不低于3个)
- 工厂设计模式 : Spring使用工厂模式通过 `BeanFactory`、`ApplicationContext` 创建 bean
对象。
- 代理设计模式 : Spring AOP 功能的实现。
- 单例设计模式 : Spring 中的 Bean 默认都是单例的。
- 模板方法模式 : Spring 中 `jdbcTemplate`、`hibernateTemplate` 等以 Template 结尾的对
数据库操作的类,它们就使用到了模板模式。
- 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
- 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
- 适配器模式: :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配`Controller`
描述Spring事务传播行为?
- REQUIRED(常用):如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。
- SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
- MANDATORY:强制的 使用当前的事务,如果当前没有事务,就抛出异常。
- REQUIRES_NEW:需要JTA事务管理器的支持,新建事务,如果当前存在事务,把当前事务挂起。
- NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- NESTED:嵌套 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与
PROPAGATION_REQUIRED类 似的操作
Spring REQUIRED和 REQUIRES_NEW区别
- 在同一个方法中,因为大多数情况是一系列业务要保证要么都成功要么都失败的,所以各个业务方法使用默认的REQUIRED方式。
- 如果一个特殊的业务方法,和其他业务不关联,给它的方法设置REQUIRES_NEW,这样就能保证其他业务有异常时也不会被回滚。
描述Spring事务的隔离级别?
1. int ISOLATION_DEFAULT = -1; 使用数据库默认的隔离级别
2. int
ISOLATION_READ_UNCOMMITTED = 1;读未提交,A事务可以读到B事务未提交的数据3. int ISOLATION_READ_COMMITTED = 2;读提交,A事务可以读到B事务已提交的数据
4. int ISOLATION_REPEATABLE_READ = 4;可重复读,A事务读不到B事务已提交的数据
5. int ISOLATION_SERIALIZABLE = 8;串行化
Spring 循环依赖
什么是循环依赖?
循环依赖其实就是循环引用,也就是两个或者两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A,
注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。
Spring中循环依赖场景有:
(1)构造器的循环依赖 (2)field属性的循环依赖 其中,构造器的循环依赖问题无法解决,只能拋出
BeanCurrentlyInCreationException异常,在解决属性循环依赖时,spring采用的是提前暴露对象的方法。
Spring怎么解决循环依赖
Spring的循环依赖的理论依据基于Java的引用传递,当获得对象的引用时,对象的属性是可以延后设置的。(但是构造器必须是在获取引用之前)
(1)createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象
(2)populateBean:填充属性,这一步主要是多bean的依赖属性进行填充
(3)initializeBean:调用spring xml中的init 方法。
从上面单例bean的初始化可以知道:循环依赖主要发生在第一、二步,也就是构造器循环依赖和field循环依赖。那么我们要解决循环引用也应该从初始化过程着手,对于单例来说,在Spring容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在Cache中,Spring为了解决单例的循环依赖问题,使用了三级缓存。
这三级缓存分别指:
singletonFactories : 单例对象工厂的cache
earlySingletonObjects :提前暴光的单例对象的Cache
singletonObjects:单例对象的cache
你所熟悉的 Spring 注解?
@Controller - 用于 Spring MVC 项目中的控制器类。
@Service - 用于服务类。
@RequestMapping - 用于在控制器处理程序方法中配置 URI 映射。
@ResponseBody - 用于发送 Object 作为响应,通常用于发送 XML 或 JSON 数据作为响应。
@PathVariable - 用于将动态值从 URI 映射到处理程序方法参数。
@Autowired - 用于在 spring bean 中自动装配依赖项。
@Qualifier - 使用 @Autowired 注解,以避免在存在多个 bean 类型实例时出现混淆。
@Scope - 用于配置 spring bean 的范围。
@Configuration,@ComponentScan 和 @Bean - 用于基于 java 的配置。
@Aspect,@Before,@After,@Around,@Pointcut - 用于切面编程(AOP)。