[Spring] 基础总结

326 阅读8分钟

spring当中的循环依赖怎么解决?Spring是默认单例支持循环

依赖注入:是在初始化时候完成的。

初始化bean----bean有个初始化过程---Spring bean的生命周期---n

Spring bean的生命周期是在哪个步骤完成的依赖注入?

bean   --------- Spring bean    是经过生命周期的,bean一定是java对象; 

java对象 ------对象 new出来,java对象不一定是bean   (没有在容器,没有生命周期)

引用:Spring源码博客

循环依赖:如何解决循环依赖问题-图解三级缓存以及循环依赖问题SpringBean生命周期

1、怎么说明 Spring默认是支持循环依赖的:

Spring在生命周期的过程中(bean初始化),当他把bean实例化之后的时候做一次判断,当前容器允不允许循环依赖,判断允不允许循环依赖是根据属性来的,这个属性(属性名:allowCircularReferences)在Spring默认是true,而属性名 Spring通过提供一个api来修改,如果不修改Spring默认就是开启循环依赖的。如果属性允许则Spring会第四次调用后置处理器。

2、可以通过多少种方式完成依赖注入

构造器注入、setter 方法注入、接口注入 ;仅使用构造器和 setter 注入;

哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入?
你两种依赖方式都可以使用,构造器注入和 Setter 方法注入。
最好的解决方案是用构造器参数实现强制依赖,setter 方法实现可选依赖。

3、spring 提供了哪些配置方式  or  如何给Spring容器提供配置元数据

基于 xml 配置 bean 所需的依赖项和服务在 XML 格式的配置文件中指定

基于注解配置 您可以通过在相关的类,方法或字段声明上使用注解

基于 Java API 配置

Spring 的 Java 配置是通过使用 @Bean 和 @Configuration 来实现。 (1) @Bean 注解扮演与 元素相同的角色。 (2) @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。 例如:

@Configuration
public class StudentConfig {
	@Bean
	public StudentBean myStudent() {
		return new StudentBean();
	}
}

4、bean的作用域

单例模式:每个bean定义只生成一个对象实例,每次getBean请求获得的都是此实例
单例模式分为:饿汉模式 和 懒汉模式

饿汉模式:spring singleton的缺省是饿汉模式:
启动容器时(即实例化容器时),为所有spring配置文件中定义的bean都生成一个实例

懒汉模式:在第一个请求时才生成一个实例,以后的请求都调用这个实例

Spring 3 中为 Bean 定义了 5 中作用域,分别为 singleton(单例)、prototype(原型)、request、session 和 global session,5 种作用域说明如下:

singleton:单例模式(多线程下不安全) 1. singleton:单例模式,Spring IoC 容器中只会存在一个共享的 Bean 实例,无论有多少个Bean 引用它,始终指向同一对象。该模式在多线程下是不安全的。Singleton 作用域是Spring 中的缺省作用域,也可以显示的将 Bean 定义为 singleton 模式 ;

prototype:原型模式每次使用时创建 2. prototype:原型模式,每次通过 Spring 容器获取 prototype 定义的 bean 时,容器都将创建一个新的 Bean 实例,每个 Bean 实例都有自己的属性和状态,而 singleton 全局只有一个对象。根据经验,对有状态的bean使用prototype作用域,而对无状态的bean使用singleton作用域。

Request:一次 request 一个实例 3. request:在一次 Http 请求中,容器会返回该 Bean 的同一实例。而对不同的 Http 请求则会产生新的 Bean,而且该 bean 仅在当前 Http Request 内有效,当前 Http 请求结束,该 bean实例也将会被销毁。

session 4. session:在一次 Http Session 中,容器会返回该 Bean 的同一实例。而对不同的 Session 请求则会创建新的实例,该 bean 实例仅在当前 Session 内有效。同 Http 请求相同,每一次session 请求创建新的实例,而不同的实例之间不共享属性,且实例仅在自己的 session 请求内有效,请求结束,则实例将被销毁。

global Session 5. global Session:在一个全局的 Http Session 中,容器会返回该 Bean 的同一个实例,仅在使用 web context 时有效。

4、如何在 spring 中启动注解装配

默认情况下,Spring 容器中未打开注解装配。因此,要使用基于注解装配,我们必须通过配置 <context:annotation-config/> 元素在 Spring 配置文件中启用它。

5、列举 spring 支持的事务管理类型

Spring 支持两种类型的事务管理:

(1)编程式事务管理:在此过程中,在编程的帮助下管理事务。它为您提供极大的灵活性,但维护起来非常困难。用户自己通过代码来控制事务的处理逻辑。
(2) 声明式事务管理:在此,事务管理与业务代码分离。仅使用注解或基于 XML的配置来管理事务。

6、、AOP 有哪些实现方式?

实现 AOP 的技术,主要分为两大类:

静态代理 指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;

动态代理 在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。包括: JDK 动态代理 / CGLIB

7、Spring事务的实现方式原理是什么?

        其实事务的操作本来应该是由数据库控制,但是为了方便用户进行业务逻辑的操作,Spring对事务功能进行了扩展实现,一般我们很少会用编程式事务,更多的是通过添加@Transactional注解来进行实现,当添加此注解之后事务的自动功能就会关闭,有Spring框架来帮助进行控制。

其实事务操作是AOP的一个核心体现(通过动态代理的方式),当一个方法添加@transactional注解之后,Spring会基于这个类生成一个代理对象(不管是jdk,还是cglib),之后会将这个代理对象作为bean,当使用这个代理对象的方法的时候,如果有事务处理,那么会先把事物的自动提交给关掉,然后去执行具体的业务逻辑,如果执行逻辑没有出现异常,那么代理逻辑当前事务就会直接提交,如果出现任何异常情况,那么直接进行回滚操作,当然用户可以控制对哪些异常进行回滚操作。     

一、spring 中bean创建的生命周期:重点看,跟之前不一样:包含二次加工

粗捏可以分为三个阶段,它是有bean的第一次加工,还有bean的第二次加工过程,首先bean的第一次加工,将你的对象实例化,在这实例化的前后,有一个BeanPostProcessor在做前置和后置处理,第二步就是它的依赖注入的过程,在这个过程之中,首先它会设置它的一个属性值,然后它对bean实现的BeanAware相关接口,像BeanNameAware,或者DisposableBean这接口的话,就会给你的bean注入相应的aware的属性,这里有2步,这两步前后也有BeanPostProcessor后处理操作,其实第二步之后,这bean已经接近一个完成期了。但它还有一个bean的二次加工,在这个二次加工前后,他也是有一个

你可以像ApplicationContext那样,配置一个自定义的后置处理bean,然后它在工程中主要是调用,你在bean中写的environment的一个方法,或者你的bean实现了一个InitializingBean,它会第二次回调你的afterPropertiesSet方法,对bean做进一步设置,bean的二次加工完成之后,你的bean就已经建立完成了,也就是说他会根据你的bean的scope,如果是一个单列的bean,默认是单例的,它就会走下去,如果是多实例,你的bean的scope是prototype,多实例的话,就会移交给你去管理它的后续的生命周期,单实例的话,生命周期还是由spring来管理的,当spring容器销毁的时候,他会调用destory方法,若你实现的是一个Disposable Bean,实现的那个接口也会有你销毁的逻辑,这是bean整个生命周期的过程。

二、Spring中bean是线程安全的吗

三、Spring中的事务是如何实现的

四、Spring容器启动流程是怎样的

五、Spring用了哪些设计模式