javaEE-Spring IOC&DI

目录

1、什么是Spring:

2.什么是IoC:

[3. 什么是控制反转呢?](#3. 什么是控制反转呢?)

4.IoC容器具备以下优点:

5.DI是什么:

依赖注⼊方法:

三种注入方法的优缺点:

@Autowired注解注入存在的问题:

@Autowired和@Resource的区别:

6.IoC和DI的使用:

7.Bean的存储:

8.Bean的命名:

[9.ApplicationContext VS BeanFactory](#9.ApplicationContext VS BeanFactory)

10.Bean的扫描路径:

[10.Spring, Spring Boot 和Spring MVC的关系以及区别:](#10.Spring, Spring Boot 和Spring MVC的关系以及区别:)

11.

12.Spring框架中的Bean是否是线程安全的:


1、什么是Spring:

Spring是一个开源框架,他让我们的开发更加简单. 他⽀持⼴泛的应⽤场景, 有着活跃⽽庞⼤的社区

,是包含了众多工具方法的IoC容器。

2.什么是IoC:

IoC: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器.

IoC 是Spring的核⼼思想,在类上⾯添加 @RestController 和 @Controller 注解, 就是把这个对象交给Spring管理, Spring 框架启动时就会加载该类. 把对象交给Spring管理, 就是IoC思想.

3. 什么是控制反转呢?

获得依赖对象的过程被反转了。也就是说, 当需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊ (Dependency Injection,DI)就可以了.

这个容器称为:IoC容器. Spring是⼀个IoC容器, 所以有时Spring 也称为Spring 容器.

4.IoC容器具备以下优点:

资源不由使⽤资源的双⽅管理,⽽由不使⽤资源的第三⽅管理,这可以带来很多好处。

第⼀,资源集中管理,实现资源的可配置和易管理。IoC容器会帮我们管理⼀些资源(对象等), 我们需要使⽤时, 只需要从IoC容器中去取就可以了

第⼆,降低了使⽤资源双⽅的依赖程度,也就是我们说的耦合度。我们在创建实例的时候不需要了解其中的细节。

Spring 就是⼀种IoC容器, 帮助我们来做了这些资源管理.

5.DI是什么:

DI: Dependency Injection(依赖注⼊)

容器在运⾏期间, 动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊。程序运⾏时需要某个资源,此时容器就为其提供这个资源。简单来说, 就是把对象取出来放到某个类的属性中.

从这点来看, 依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。可以说,DI 是IoC的⼀种实现.

依赖注⼊方法:

Spring也给我们提供了三种⽅式:

  1. 属性注⼊(Field Injection):使用@Autowired实现

  2. 构造⽅法注⼊(Constructor Injection):在类的构造⽅法中实现注⼊,搭配@Autowired注解

注意事项:如果类只有⼀个构造⽅法,那么 @Autowired 注解可以省略;如果类中有多个构造⽅法,那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法

  1. Setter 注⼊(Setter Injection):和属性的 Setter ⽅法实现类似,只不过在设置 set ⽅法的时候需要加上 @Autowired 注解 。

三种注入方法的优缺点:

属性注入:

优点:代码简介,使用简单。

缺点:只能作用于 IoC容器,不能注入final修饰的类。

构造方法注入:

优点:可以注⼊final修饰的属性 ; 注⼊的对象不会被修改;依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法是在类加载阶段就会执⾏的⽅法;通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的。

缺点: 注⼊多个对象时, 代码会⽐较繁琐

• Setter注⼊

优点: ⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊

缺点: 不能注⼊⼀个Final修饰的属性;注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤, 就有被修改的⻛险

@Autowired注解注入存在的问题:

当同⼀类型存在多个bean时,仅通过类 类型注入时,会找到非唯一的Bean对象。

可以通过一下方法解决:

  1. @Primary注解:当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现.

  2. @Qualifier注解:通过该注解的value属性,指定当前要注入的Bean的名称;不能单独使用,要搭配@Autowired注解使用。

3.@Resource注解:按照Bean的名称注入,通过name属性指定要注入的Bean的名称。

@Autowired和@Resource的区别:

相同点:

  1. @Resource和@Autowired都是做bean的注入时使用。

2.两者都可以写在字段和setter方法上;

不同点:

1.@Autowired是Spring框架提供的注解;@Resource并不是Spring的注解,是JDK提供的注解,它的包是javax.annotation.Resource,需要导入;

2.@Autowired是按照类型注入的,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用;

@Resource是按照名称注入的,@Resource有两个重要的属性: name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。

@Resource装配顺序:

①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。

④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

6.IoC和DI的使用:

Spring 容器 管理的主要是对象, 这些对象, 我们称之为"Bean". 我们把这些对象交由Spring管理, 由Spring来负责对象的创建和销毁(实现作为容器的存和取的功能).

7.Bean的存储:

要把某个对象交给IOC容器管理,需要在类上添加⼀个注解: @Component ,⽽Spring框架为了更好的服务web应⽤程序, 提供了更丰富的注解:

  1. 类注解:

@Controller(控制器存储):控制层, 接收请求, 对请求进⾏处理, 并进⾏响应

@Service(服务存储):业务逻辑层, 处理具体的业务逻辑

@Repository(仓库存储):数据访问层,也称为持久层. 负责数据访问操作

@Configuration(配置存储):配置层. 处理项⽬中的⼀些配置信息

@Component(组件存储):该注解是一个元注解,这几个注解是该注解的衍生类。

  1. ⽅法注解:@Bean.

**分配这么多注解的作用:**和应⽤分层是呼应的. 让程序员看到类注解之后,就能直接了解当前类的⽤途。

方法注解的使用场景:

  1. 使⽤外部包⾥的类, 没办法添加类注解

  2. ⼀个类, 需要多个对象, ⽐如多个数据源 。这种场景, 我们就需要使⽤⽅法注解 @Bean

(方法注解要配合类注解使用)

8.Bean的命名:

程序开发⼈员不需要为bean指定名称(BeanId), 如果没有显式的提供名称(BeanId),Spring容器将为该bean⽣成唯⼀的名称。命名约定使⽤Java标准约定作为实例字段名. 也就是说,bean名称以⼩写字⺟开头,然后使⽤驼峰式⼤⼩写.

⽐如:

类名: UserController, Bean的名称为: userController

类名: AccountManager, Bean的名称为: accountManager

当有多个字符并且第⼀个和第⼆个字符都是⼤写时, 将保留原始的⼤⼩写。

⽐如

类名: UController, Bean的名称为: UController

类名: AManager, Bean的名称为: AManager

9.ApplicationContext VS BeanFactory

获取bean对象, 是ApplicationContext的⽗类BeanFactory提供的功能。

• 继承关系和功能⽅⾯来说:

Spring 容器有两个顶级的接⼝:BeanFactory 和ApplicationContext。其中 BeanFactory 提供了基础的访问容器的能⼒,⽽ApplicationContext 属于 BeanFactory 的⼦类,还实现了多个别的接口,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持.

• 从性能⽅⾯来说:延迟加载

  1. BeanFactroy 采用的是延迟加载形式来注入 Bean 的,即只有在使用到某个 Bean 时(调用getBean()),才对该 Bean 进行加载实例化。这样,我们就不能发现一些存在的 spring 的配置问题。而 ApplicationContext 则相反,它是在容器启动时,一次性创建了所有的 Bean。这样,在容器启动时,我们就可以发现 Spring 中存在的配置错误

10.Bean的扫描路径:

使⽤五⼤注解声明的bean,要想⽣效, 还需要配置扫描路径, 让Spring扫描到这些注解 也就是通过 @ComponentScan 来配置扫描路径。

在之前的使用中@ComponentScan 注解虽然没有显式配置,但也访问成功了,是因为该注解已经包含在了启动类声明注解@SpringBootApplication 中了,默认扫描的范围是SpringBoot启动类所在包及其⼦包,在配置类上添加 @ComponentScan 注解, 该注解默认会扫描该类所在的包下所有的配置类。

10.Spring, Spring Boot 和Spring MVC的关系以及区别:

Spring: Spring 是⼀个开发应⽤框架,特点是:轻量级、⼀站式、模块化,其⽬的是⽤于简化企业级应⽤程序开发.

Spring的主要功能: 管理对象,以及对象之间的依赖关系, ⾯向切⾯编程, 数据库事务管理, 数据访问, web框架⽀持等。但是Spring具备⾼度可开放性, 并不强制依赖Spring。

Spring MVC: Spring MVC是Spring的⼀个⼦框架, 按照MVC模式设计了⼀个 MVC框架(⼀些⽤Spring 解耦的组件), 主要⽤于开发WEB应⽤和⽹络接⼝,Spring MVC 是⼀个Web框架。

Spring Boot: Spring Boot是对Spring的⼀个封装, 为了简化Spring应⽤的开发⽽出现的,使⽤Spring Boot 可以更加快速的搭建框架, 降级开发成本, 让开发⼈员更加专注于Spring应⽤的开发,⽽⽆需过多关注XML的配置和⼀些底层的实现。

pring MVC和Spring Boot都属于Spring,Spring MVC 是基于Spring的⼀个 MVC 框架,⽽Spring Boot 是基于Spring的⼀套快速开发整合包.

11.

12.Spring框架中的Bean是否是线程安全的:

Spring 框架并没有对单例 Bean 进行任何多线程的封装处理。

关于单例 Bean 的线程安全和并发问题,需要开发者自行去搞定。单例的线程安全问题,并不是 Spring 应该去关心的。 Spring 应该做的是,提供根据配置,创建单例 Bean 或多例 Bean 的功能。但实际上,大部分的 Spring Bean 并没有可变的状态,所以在某种程度上说 Spring 的单例Bean 是线程安全的。如果你的 Bean 有多种状态的话,就需要自行保证线程安全。最浅显的解决办法,就是将多态 Bean 的作用域(Scope)由 Singleton 变更为 Prototype。

13.Spring如何解决循环依赖问题:

循环依赖:循环引用,就是两个或两个以上的bean对象互相持有对方,最终形成了闭环,如:A引用B,B引用C,C又引用A,就形成了循环引用。

处理整个流程大致如下:

  1. 首先 A 完成初始化第一步并将自己提前曝光出来(通过 ObjectFactory 将自己提前曝光),在初始化的时候,发现自己依赖对象 B,此时就会去尝试 get(B),这个时候发现 B 还没有被创建出来;

  2. 然后 B 就走创建流程,在 B 初始化的时候,同样发现自己依赖 C,C 也没有被创建出来;

  3. 这个时候 C 又开始初始化进程,但是在初始化的过程中发现自己依赖 A,于是尝试 get(A)。这

个时候由于 A 已经添加至缓存中(一般都是添加至三级缓存 singletonFactories),通过ObjectFactory 提前曝光,所以可以通过 ObjectFactory#getObject() 方法来拿到 A 对象。 C 拿到 A 对象后顺利完成初始化,然后将自己添加到一级缓存中;

  1. 回到 B, B 也可以拿到 C 对象,完成初始化, A 可以顺利拿到 B 完成初始化。到这里整个链路

就已经完成了初始化过程了。

相关推荐
缺点内向19 小时前
Java:创建、读取或更新 Excel 文档
java·excel
带刺的坐椅20 小时前
Solon v3.4.7, v3.5.6, v3.6.1 发布(国产优秀应用开发框架)
java·spring·solon
四谎真好看21 小时前
Java 黑马程序员学习笔记(进阶篇18)
java·笔记·学习·学习笔记
桦说编程21 小时前
深入解析CompletableFuture源码实现(2)———双源输入
java·后端·源码
java_t_t21 小时前
ZIP工具类
java·zip
lang201509281 天前
Spring Boot优雅关闭全解析
java·spring boot·后端
pengzhuofan1 天前
第10章 Maven
java·maven
百锦再1 天前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
刘一说1 天前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多1 天前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring