目录
🌴什么是依赖注入
🎄依赖注入的三种方法
🚩属性注⼊(Field Injection)
🚩Setter注入
🚩构造方法注入
🚩三种注⼊的优缺点
🌳@Autowired存在的问题
🌲解决@Autowired存在的问题
🚩@Primary注解
🚩@Qualifier注解
🚩bean对象名称与属性名相匹配
🚩@Resource注解
🍃@Autowired注入过程
🍀@Autowird与@Resource的区别
🎋图书管理系统代码改动
🎍Spring, Spring Boot和SpringMVC的关系以及区别
🌴什么是依赖注入
依赖注⼊是⼀个过程,是指IoC容器在创建Bean时,去提供运⾏时所依赖的资源,⽽资源指的就是对象.
在上⾯程序案例中,我们使⽤了 @Autowired 这个注解,完成了依赖注⼊的操作
简单来说,就是把对象取出来放到某个类的属性中.
在 ⼀些⽂章中,依赖注⼊也被称之为"对象注⼊","属性装配",具体含义需要结合⽂章的上下⽂来理解
🎄依赖注入的三种方法
关于依赖注⼊,Spring也给我们提供了三种⽅式:
- 属性注入(Field Injection)
- 构造方法注入(Constructor Injection)
- Setter注入(Setter Injection)
接下来,我们分别来看。 下⾯我们按照实际开发中的模式
🚩属性注⼊(Field Injection)
属性注⼊是使⽤ @Autowired 实现的。
比如将UserService类注⼊到UserController类中。
UserService代码:
UserController代码:
获取对象:
运行结果:
若将@Tutowired注释掉,运行时就会报空指针异常,也就是说userService是空的,并没有注入
🚩Setter注入
Setter注⼊和属性的Setter⽅法实现类似,只不过在设置set⽅法的时候需要加上@Autowired注解
运行结果:
🚩构造方法注入
代码:
运行结果:发现没有加@Autowired注解,却注入成功了。
我们说,加了有参的构造函数之后,也需要把无参的构造函数加上,那再加上试试
运行结果:此时就异常了;我们在创建对象时,要么去new,或者通过反射的方式创建对象,这里我们也没有看到spring去new对象,所以这里spring是通过反射的方式去创建对象的,不管是new还是反射创建,都需要去调用构造函数,那么只有一个构造函数,spring就不得不用这个,那么使用了这个有参的构造函数,发现需要一个UserService,它就去容器里面查找有没有UserService这个对象,发现有就把它放进来了,完成了UserService的创建。当我们加上无参的构造函数时,它就使用了无参的构造函数,但是无参的构造函数没有给userService赋值,所以就报了空指针;即有多个构造函数时,就需要告诉spring使用哪个来创建对象,加上@Autowired注解即可。
代码:
运行结果:
🚩三种注⼊的优缺点
属性注⼊:
-
优点:
- 简洁,使⽤⽅便;
-
缺点:
-
只能⽤于IoC容器,如果是⾮IoC容器不可⽤,并且只有在使⽤的时候才会出现NPE(空指针异常)
-
不能注⼊⼀个Final修饰的属性
-
构造函数注⼊(Spring 4.X推荐):
- 优点:
-
可以注⼊final修饰的属性
-
注⼊的对象不会被修改
-
依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法是在类加载阶段就会执⾏的⽅法.
-
通⽤性好,构造⽅法是JDK⽀持的,所以更换任何框架,他都是适⽤的
-
- 缺点:
- 注⼊多个对象时,代码会⽐较繁琐
Setter注⼊(Spring3.X推荐):
-
优点:
- ⽅便在类实例之后,重新对该对象进⾏配置或者注⼊
-
缺点:
-
不能注⼊⼀个Final修饰的属性
-
注⼊对象可能会被改变,因为setter⽅法可能会被多次调⽤,就有被修改的⻛险.
-
🌳@Autowired存在的问题
当同⼀类型存在多个bean时,在使⽤@Autowired就会存在问题
例如有以下代码:
在UserController中注入对象:
运行结果:
报错的原因是,⾮唯⼀的 Bean 对象,也就是说它不知道注入哪个对象了
🌲解决@Autowired存在的问题
为了解决上述问题,Spring提供了以下4种解决⽅案:
- @Primary
- @Qualifierbean
- 对象名称与属性名相匹配
- @Resource
🚩@Primary注解
使⽤@Primary注解:当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现.
运行结果:
🚩@Qualifier注解
使⽤@Qualifier注解:指定当前要注⼊的bean对象。在@Qualifier的value属性中,指定注⼊的bean的名称。
代码:
运行结果:
🚩bean对象名称与属性名相匹配
代码:
运行结果:
🚩@Resource注解
这个注解也是指定对象的名称
代码:
运行结果:
注意:
- 前面三种方式都是spring提供的,@Resource现在是jakarat这个包里面,在JDK8的时候是在JDK里面,@Qualifier注解不能单独使⽤,必须配合@Autowired使⽤
🍃@Autowired注入过程
🍀@Autowird与@Resource的区别
- @Autowired是spring框架提供的注解,⽽@Resource是jakarta提供的注解
- @Autowired默认是按照类型注⼊,⽽@Resource是按照名称注⼊.相⽐于@Autowired来说,@Resource⽀持更多的参数设置,例如:name设置,根据名称获取Bean。
🎋图书管理系统代码改动
通过上⾯的学习,我们把前⾯的图书管理系统代码进⾏调整
Service层的注解,改成@Service
Dao层的注解,改成@Repository
重新运⾏代码,验证程序访问正常
代码:
项目启动,访问页面:可以正常访问
🎍Spring, Spring Boot和SpringMVC的关系以及区别
Spring: 简单来说,Spring是⼀个开发应⽤框架,什么样的框架呢,有这么⼏个标签:轻量级、⼀ 站式、模块化,其⽬的是⽤于简化企业级应⽤程序开发
Spring的主要功能:管理对象,以及对象之间的依赖关系,⾯向切⾯编程,数据库事务管理,数据访 问,web框架⽀持等.
但是Spring具备⾼度可开放性,并不强制依赖Spring,开发者可以⾃由选择Spring的部分或者全 部,Spring可以⽆缝继承第三⽅框架,⽐如数据访问框架(Hibernate、JPA),web框架(如Struts、 JSF)
Spring MVC:SpringMVC是Spring的⼀个⼦框架,Spring诞⽣之后,⼤家觉得很好⽤,于是按照MVC 模式设计了⼀个MVC框架(⼀些⽤Spring解耦的组件),主要⽤于开发WEB应⽤和⽹络接⼝,所以, Spring MVC是⼀个Web框架
Spring MVC基于Spring进⾏开发的,天⽣的与Spring框架集成.可以让我们更简洁的进⾏Web层 开发,⽀持灵活的URL到⻚⾯控制器的映射,提供了强⼤的约定⼤于配置的契约式编程⽀持,⾮常 容易与其他视图框架集成,如Velocity、FreeMarker等
Spring Boot: Spring Boot是对Spring的⼀个封装,为了简化Spring应⽤的开发⽽出现的,中⼩型 企业,没有成本研究⾃⼰的框架,使⽤SpringBoot可以更加快速的搭建框架,降级开发成本,让开发 ⼈员更加专注于Spring应⽤的开发,⽽⽆需过多关注XML的配置和⼀些底层的实现.
Spring Boot 是个脚⼿架,插拔式搭建项⽬,可以快速的集成其他框架进来
⽐如想使⽤SpringBoot开发Web项⽬,只需要引⼊SpringMVC框架即可,Web开发的⼯作是 SpringMVC完成的,⽽不是SpringBoot,想完成数据访问,只需要引⼊Mybatis框架即可
Spring Boot只是辅助简化项⽬开发的,让开发变得更加简单,甚⾄不需要额外的web服务器,直接 ⽣成jar包执⾏即可.
总结:
SpringMVC和SpringBoot都属于Spring,SpringMVC是基于Spring的⼀个 MVC框架,⽽SpringBoot是基于Spring的⼀套快速开发整合包.
⽐如我们的图书系统代码中
整体框架是通过SpringBoot搭建的
IoC, DI功能是Spring的提供的, web相关功能是SpringMVC提供的
这三者专注的领域不同,解决的问题也不⼀样,总的来说,Spring就像⼀个⼤家族,有众多衍⽣产 品,但他们的基础都是Spring,⽤⼀张图来表⽰他们三个的关系: