Bootstrap

Spring IoC与依赖注入

White graces:个人主页

🙉专栏推荐:Java入门知识🙉

🐹今日诗词:春有百花秋有月,夏有凉风冬有雪🐹


⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏

⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏


目录

Spring

Spring IoC

传统程序和IoC程序

传统方式

如何把对象放到Spring中

如何从Spring中取出对象

Spring存储对象

IoC注解的应用

@Controller注解

@Controller的使用

@Service的使用

从容器获取对象的常用方式

根据类型从容器获取对象

根据名称从容器获取对象

Spring容器对象命名规范

根据类型和名称从容器获取对象

@Repository

@Component

@Configuration

五大注解的关系

@Bean注解(方法注解)

注解重命名

Spring扫描路径

指定扫描路径

依赖注入

属性注入

Setter方法注入

构造方法注入

三种注入方式的差异性(重点)

@Autowired注解存在的问题

@Primary注解

@Qualifier注解

@Resource注解

四种注入方式选择哪种比较好

@Autowired注入过程

美图分享


Spring

容器

介绍Spring IoC, 首先要了解容器的概念

容器: 可以容纳对象, 例如链表, 队列, 堆, map....

Spring也是一个容器, 它容纳的是一个Bean对象

Java SE的Bean对象指的是实体类

Spring的Bean对象指的是Spring管理的对象, 例如这个

Spring IoC

IoC(Inversion of Controller): 控制反转

前面通过@RestController和@Controller注解, 把类交给Spring去管理, 这个思想就是IoC思想

控制反转: 指的是控制权反转

比如汽车驾驶: 以前是驾驶员开车, 现在可以交给自动化驾驶系统, 这也属于控制反转

我们接下以 制造一个汽车 为例子 来对比传统方式和IoC方式

传统程序和IoC程序

传统方式

要想汽车跑,需要先造一个汽车

造汽车,需要先造车身

造车身,需要先造底盘

造底盘,需要先造轮胎

确定轮胎尺寸并制造

于是汽车就可以运行了

传统方式问题

可维护性太差,当最底层代码改动之后, 整个调⽤链上的所有代码都需要修改, 牵一发而动全身

比如客户想要不同的轮胎大小, 我们按需求设计轮胎大小, 在轮胎类构造方法里传入size, 

会报错, 整个调⽤链上的所有代码都需要修改

IoC方式

IoC写法需要对代码进行修改, 需要对象时,传一个对象, 这个对象可以从Spring中拿

因为我们把对象交给Spring去管理, 如果我们需要, Spring就会帮我们创建

优点

代码耦合性低, 增加需求对其他类和方法影响很小



如何把对象放到Spring中

@Component注解: 把对象放到Spring中

@Component注解是加在类上

如何从Spring中取出对象

@Autowired注解: 从Spring中取出对象, 注入到对象的使用方(这个过程叫依赖注入, 又称Di)

@Autowired注解是加在对象上的

Spring存储对象

通过Spring容器存储对象, 一般通过注解从容器获取对象, 注解类型有两种:

类注解: @Controller, @Service, @Repository, @Componment, @Configuration(五大注解)

方法注解: @Bean(唯一)

IoC注解的应用

@Controller注解

前面我们也了解过, @Controller注解有很多功能,

在Spring知识里, 被@Controller注解标记的类, 在Spring容器启动时, 会创建实例并作为bean对象存储到容器中

@Controller其他作用: 

  • 请求映射: 能够将Http的 URL 请求映射到相应的方法上
  • 视图解析:通常会返回一个视图
  • 标识控制器:用于标识一个类为Spring MVC的控制器, 表示这个类是处理用户请求的组件

@Controller的使用

我们不手动创建对象, 借助@Controller注解和Spring容器来调用对象的方法, 例如

@Service的使用

使用方式和@Controller注解一样, 加在类上的

@Service注解用于标记业务逻辑层访问对象

@Service注解标记的类, 在Spring容器启动时, 会创建实例作为bean对象存储到容器中

从容器获取对象的常用方式

我们一般通过ApplicationContext接口的方法从容器获取对象

ApplicationContext接口的getBean方法有很多种重载方式

我们介绍一下常见的三种

根据类型从容器获取对象

方法: getBean(Class<T> requiredType)

括号里填: 要获取对象的类型

这串代码要获取对象的类型是UserService

根据名称从容器获取对象

方法: getBean(String name)

name: 是容器创建对象的名称

那么我怎么知道容器创建对象叫啥名呢?

Spring容器对象命名规范

五大注解命名规则: 一般情况采用小驼峰的形式

即首字母小写, 后续单词的首字母大写, 没有空格或下划线

例如: UserController ------->  userController

特殊情况, 如果类名第一个字母和第二个字母都是大写, 则容器对象名保持不变

例如UController ------> UController

方法注解: @Bean注解命名规范

如果是@Bean注解: 容器对象名称是方法名

根据类型和名称从容器获取对象

方法: getBean(String name, Class<T> requiredType)

双重保险: 根据类型名称从容器中获取对象

Spring创建对象是单例模式, 我们每次从容器获取一个Bean时,都会返回同一个实例

所以三次获取输出都是同一个实例

@Repository

@Repository用于标识数据访问对象(DAO)

@Repository注解标记的类, 在Spring容器启动时, 会创建实例并作为bean对象存储到容器中

@Component

@Component是一个通用的标记注解,适用于任何需要被Spring管理的类

@Configuration

用于定义应用的Bean配置

@Configuration注解标记的类, 在Spring容器启动时, 会创建实例并作为bean对象存储到容器中

五大注解的关系

@Bean注解(方法注解)

作用: Spring会将 被@Bean注解标记的方法 的返回值作为示例放在容器中

@Bean注解要搭配类注解使用, 没有类哪来的方法

前面的五大注解是单例模式实现的, 每次请求都只返回一个实例

如果想要返回多个对象需要用到@Bean注解

注解重命名

如果不想用Spring提供的容器名称, 我们也是可以自己命名的

五大注解重命名: 直接在注解后面加括号重命名即可

例如@Reposiotry("name")

在Spring容器的名称: 和Spring默认的规则无关, 你起啥名, 在容器里面还是啥名

方法注解重命名@Bean
分两种情况, 一种和五大注解命名方法一样

另一种: 同一个Bean对象定义多个名称, 重命名多个名称采用数数组的形式

@Bean( {"name1", "name2"} )

两个名字, 都指向同一个对象

Spring扫描路径

前面我们学了Spring会扫描加注解的类并执行, 并不是所有加注解的类都会被扫描到

必须是和启动类所在路径相同的路径或其子路径, 并且加了注解才会扫描

毕竟子目录不能扫描父目录

我们把启动类挪到Repository包下

指定扫描路径

@ComponentScan(文件路径)

依赖注入

依赖注入分三种: 属性注入, Setter方法注入, 构造方法注入

依赖注入和五大注解一样, 也是将类对象交给Spring容器去管理

疑问: 五大注解不是已经交给容器进行管理了吗, 为什么还要依赖注入?

答: 他们之间是相辅相成的, 有了五大注解并不代表就不要依赖注入了,

     就像有女朋友, 不一定代表就不能找小三了(请勿代入)

有时候即使一个类被五大注解标注, 但是类中还是有可能会用到其他类里的字段, 我们使用其他类的字段或方法时仍然需要手动new

而依赖注入是将对象的依赖关系管理交给Spring容器来完成,而不是由类本身来创建和管理这些依赖.

属性注入

语法: 在需要注入的属性前面加上@Autowired注解

         Spring就会帮我们把创建好的对象赋值给声明的属性了

首先要声明可能要用到的类, 只是声明, 并不是创建对象, 赋值对象的过程交给Spring容器

属性是

Setter方法注入

语法: 在Setter方法前面加上@Autowired注解, Spring就会帮我们注入了

构造方法注入

语法: 在有参构造方法前面加上@Autowired注解即可

三种注入方式的差异性(重点)

@Autowired注解存在的问题

问题: 当存在多个相同类型的Bean注入时,会导致Spring无法确定要注入哪一个Bean.

@Primary注解

作用: @Primary注解用于标记优先注入的Bean,当有多个相同类型的Bean时,Spring会优先选择标有@Primary注解的Bean对象

@Qualifier注解

作用: 如果Spring有多个相同类型的Bean, 可以使用@Qualifier注解指定具体要注入的Bean

这种注入方法使用的更多, 因此@Qualifier注解可读性更高, 是加在要注入对象前面的, 而@Primary注解是

加在创建对象的时候

@Resource注解

@Resource注解是JDK包里的, 也可以用于依赖注入

作用: Resource用于自动注入Bean,根据名称类型进行注入, 一般多用于根据名称注入

此外还有一种方式不同@Primary和@Qualifier和@Resource注解实现注入的方式

方法: 让创建的对象名和容器中的Bean名相同

四种注入方式选择哪种比较好

通常情况下,我们认为:
@Autowired适用于一个类只有一个对象,如果有多个对象
一般会使用@Resource来完成注入

@Autowired注入过程

美图分享

;