从0开始回顾Spring---系列一

简介: IOC1、什么是IOC?什么是DI?IOClOC:控制反转,以前创建对象的时候都需要自己手动的new,而现在创建对象的任务全部交给spring来管理,降低了对象之间的耦合,当我们需要使用这个对象的时候直接从IOC中获取就行了。DIDI(依赖注入):指的是容器在实例化对象的时候把它依赖的类注入给它。2、IOC的实现原理?Spring的IoC的底层实现原理是工厂模式+反射+XML配置文件 。即先写一个接口,再写该接口的一个实现类,通过解析XML配置文件获取该实现类的配置属性,在工厂类中使用反射机制得到实现类相应的对象。3、 说说BeanFactory和ApplicantCon

IOC

1、什么是IOC?什么是DI?


IOC

lOC:控制反转以前创建对象的时候都需要自己手动的new,而现在创建对象的任务全部交给spring来管理,降低了对象之间的耦合,当我们需要使用这个对象的时候直接从IOC中获取就行了。

DI

DI(依赖注入)指的是容器在实例化对象的时候把它依赖的类注入给它。

2、IOC的实现原理?


Spring的IoC的底层实现原理是工厂模式+反射+XML配置文件 。即先写一个接口,再写该接口的一个实现类,通过解析XML配置文件获取该实现类的配置属性,在工厂类中使用反射机制得到实现类相应的对象。

3、 说说BeanFactory和ApplicantContext?

可以这么形容,BeanFactory是Spring的“心脏”ApplicantContext是完整的“身躯”

  • BeanFactory(Bean工厂)是Spring框架的基础设施,面向Spring本身。
  • ApplicantContext(应用上下文)建立在BeanFactoty基础上,面向使用Spring框架的开发者

BeanFactory 接口

BeanFactory是类的通用工厂,可以创建并管理各种类的对象。

ApplicationContext 接口

ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。可以这么说,使用BeanFactory就是手动档,使用ApplicationContext就是自动档。

4、Spring中的bean生命周期?


Spring IOC 中Bean的生命周期大致分为四个阶段:实例化属性赋值初始化销毁

创建过程:

  1. 实例化:第 1 步,实例化一个 Bean 对象;
  2. 属性赋值:第 2 步,为 Bean 设置相关属性和依赖;
  3. 初始化:3、4 步为在初始化前执行,5、6步是真正的初始化,第 7 步在初始化后执行,初始化完成之后,Bean就可以被使用了;
  4. 销毁:第 8~10步,第8步其实也可以算到销毁阶段,但不是真正意义上的销毁,而是先在使用前注册了销毁的相关调用接口,为了后面第9、10步真正销毁 Bean 时再执行相应的方法。


5、什么是依赖注入?依赖注入的方式有哪些?


依赖注入 :指的是容器在实例化对象的时候把它依赖的类注入给它。

依赖注入可以通过三种方式完成:

  1. 构造方法注入
  • 如果只有一个有参数的构造方法并且参数类型与注入的bean的类型匹配,那就会注入到该构造方法中。  
  1. Setter注入
  • 在XML中写入,然后在set方法中注入。
  1. 基于注解的注入
  • @Autowired(构造,接口,方法)
    自动装配,默认根据类型注入  。

6、Spring有哪些自动装配的方式?


自动装配:

  • Spring IOC容器知道所有Bean的配置信息,此外,通过Java反射机制还可以获知实现类的结构信息,如构造方法的结构、属性等信息。掌握所有Bean的这些信息后,Spring IOC容器就可以按照某种规则对容器中的Bean进行自动装配,而无须通过显式的方式进行依赖配置。

Spring提供了哪几种自动装配类型?

Spring提供了4种自动装配类型:

  1. byName:根据名称进行自动匹配;
  2. byType:根据类型进行自动匹配;
  3. constructor:与 byType类似, 只不过它是针对构造函数注入而言的。如果容器中没有找到和构造函数入参匹配类型的Bean,则Spring将抛出异常。
  4. autodetect:根据Bean的自省机制决定采用byType还是constructor进行自动装配,如果Bean提供了默认的构造函数,则采用byType,否则采用constructor。

7、Spring 中的 Bean 的作用域有哪些?

Spring的Bean主要支持五种作用域:

  1. singleton : 单例,在Spring容器仅存在一个Bean实例,Bean以单实例的方式存在,是Bean默认的作用域。
  2. prototype : 多例,每次从容器重调用Bean时,都会返回一个新的实例。
  3. request : 每一次HTTP请求都会产生一个新的Bean,该Bean仅在当前HTTP Request内有效。
  4. session : 同一个HTTP Session共享一个Bean,不同的HTTP Session使用不同的Bean。
  5. globalSession:同一个全局Session共享一个Bean,只用于基于Protlet的Web应用,Spring5中已经不存在了。

8、Spring 中的单例 Bean 会存在线程安全问题吗?


Spring中的单例Bean不是线程安全的

  • 因为单例Bean,是全局只有一个Bean,所有线程共享。如果说单例Bean,是一个无状态的,也就是线程中的操作不会对Bean中的成员变量执行查询以外的操作,那么这个单例Bean是线程安全的。比如Spring mvc 的 Controller、Service、Dao等,这些Bean大多是无状态的,只关注于方法本身。
  • 假如这个Bean是有状态的,也就是会对Bean中的成员变量进行写操作,那么可能就存在线程安全的问题。

单例Bean线程安全问题怎么解决呢?

  • 将Bean中的成员变量保存在ThreadLocal中;
  • 我们知道ThredLoca能保证多线程下变量的隔离,可以在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal里,这是推荐的一种方式。

9、循环依赖?

Spring 循环依赖:简单说就是自己依赖自己,或者和别的Bean相互依赖。

只有单例的Bean才存在循环依赖的情况原型(Prototype)情况下,Spring会直接抛出异常。原因很简单,AB循环依赖,A实例化的时候,发现依赖B,创建B实例,创建B的时候发现需要A,创建A1实例……无限套娃,会直接把系统整垮。

10、Spring如何解决循环依赖?


我们都知道,单例Bean初始化完成,要经历三步:

注入就发生在第二步,属性赋值,结合这个过程,Spring 通过三级缓存解决了循环依赖:

  1. 一级缓存 : Map<String,Object> singletonObjects ,单例池,保存实例化、属性赋值(注入)、初始化完成的 bean 实例;
  2. 二级缓存 : Map<String,Object> earlySingletonObjects ,早期曝光对象,用于保存实例完成的 bean 实例;
  3. 三级缓存 : Map<String,ObjectFactory<?>> singletonFactories ,早期曝光对象工厂,用于保存 bean 创建工厂,以便于后面扩展有机会创建代理对象。

三级缓存解决循环依赖的过程:

  • 当 A、B 两个类发生循环依赖时:

  • A实例的初始化过程:
  1. 创建A实例,实例化的时候把A对象工厂放⼊三级缓存,表示A开始实例化了,虽然我这个对象还不完整,但是先曝光出来让大家知道;

  1. A注⼊属性时,发现依赖B,此时B还没有被创建出来,所以去实例化B;
  2. 同样,B注入属性时发现依赖A,它就会从缓存里找A对象。依次从⼀级到三级缓存查询A,从三级缓存通过对象工厂拿到A,发现A虽然不太完善,但是存在,把A放⼊二级缓存,同时删除三级缓存中的A,此时,B已经实例化并且初始化完成,把B放入⼀级缓存;

  1. 接着A继续属性赋值,顺利从⼀级缓存拿到实例化且初始化完成的B对象,A对象创建也完成,删除二级缓存中的A,同时把A放入⼀级缓存;
  2. 最后,⼀级缓存中保存着实例化、初始化都完成的A、B对象;

11、为什么要三级缓存?二级不行吗?


不行,主要是为了生成代理对象。如果是没有代理的情况下,使用二级缓存解决循环依赖也是OK的。但是如果存在代理,三级没有问题,二级就不行了。

  1. 因为三级缓存中放的是生成具体对象的匿名内部类,获取Object的时候,它可以生成代理对象,也可以返回普通对象。使用三级缓存主要是为了保证不管什么时候使用的都是⼀个对象。
  2. 假设只有二级缓存的情况,往二级缓存中放的显示⼀个普通的Bean对象,Bean初始化过程中,通过 BeanPostProcessor 去生成代理对象之后,覆盖掉二级缓存中的普通Bean对象,那么 可能就导致取到的Bean对象不⼀致了。
相关文章
|
6月前
|
前端开发 Java 数据库连接
从0开始回顾Spring---系列一
基础 1、Spring是什么?有哪些特性? Spring是什么? ● Spring 是一个轻量级、非入侵式的控制反转 (IoC) 和面向切面 (AOP) 的框架。 Spring有哪些特性呢?(优点) 1. IOC 和 DI 的支持 ● Spring 的核心就是一个大的工厂容器,可以维护所有对象的创建和依赖关系,Spring 工厂用于生成 Bean,并且管理 Bean 的生命周期,实现高内聚低耦合的设计理念。 2. AOP 编程的支持 ● Spring 提供了面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等切面功能。 3. 声明式事务的支持 ● 支持通过配置就来完成对事务的管理,而不
|
6月前
|
Java 关系型数据库 MySQL
从0开始回顾Spring---系列三
AOP 1、什么是AOP? AOP概念: 面向切面编程,主要将一些与业务代码不相关,但却对多个对象产生影响的公共行为和逻辑,抽取到一个独立的模块中,让业务逻辑更加清爽。 AOP好处: AOP 可以将遍布应用各处的功能分离出来形成可重用的组件。 在编译期间、装载期间或运行期间实现在不修改源代码的情况下给程序动态添加功能。从而实现对业务逻辑的隔离,提高代码的模块化能力。 2、AOP实现原理? 实现 AOP 的技术,主要分为两大类: 静态代理 - 指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强; 动态代理 - 在运行时在内存中“临时”生成 AO
|
11月前
|
Java Spring
spring---aop简介
spring---aop简介
54 0
|
XML druid Java
|
SQL XML Java
Spring--Spring5总结
Spring--Spring5总结
85 0
|
设计模式 XML Java
Spring--Spring5入门
Spring--Spring5入门
116 0
|
Java Spring
Spring Boot 学习01-----搭建一个简单的spring-boot-demo
今天开始要系统性的学习Spring Boot。这个熟悉又陌生的框架,已经陪伴了我2年多。百尺竿头更进一步,这里使用Idea来搭建一个SpringBoot项目。
273 0
Spring Boot 学习01-----搭建一个简单的spring-boot-demo
|
SQL Java 数据库连接
Spring与SpringBoot整合Spring Data JPA及使用(一)
Spring与SpringBoot整合Spring Data JPA及使用
214 0
Spring与SpringBoot整合Spring Data JPA及使用(一)
|
Java Spring
Spring与SpringBoot整合Spring Data JPA及使用(二)
Spring与SpringBoot整合Spring Data JPA及使用
198 0
Spring与SpringBoot整合Spring Data JPA及使用(二)
|
Java 数据库 Spring
Spring与SpringBoot整合Spring Data JPA及使用(三)
Spring与SpringBoot整合Spring Data JPA及使用
133 0
Spring与SpringBoot整合Spring Data JPA及使用(三)
下一篇
无影云桌面