前言
前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了。。。事后回家想了想这一块确实有点难度的就写篇文章把我自己知道的和网上整理的分享给大家,至少大家在被问到这一块的时候能答上来,不会因为这个被卡涨薪。话不多说,满满的干货都在下面了!
1.什么是Spring的依赖注入?
依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。
2. IOC的作用
降低程序间的耦合(依赖关系)
依赖关系的管理:
以后都交给spring来维护
在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护,就称之为依赖注入。
3.Spring依赖注入的几种方式
能注入的数据:有三类
基本类型和String。
其他bean类型(在配置文件中或者注解配置过的bean)。
复杂类型/集合类型。
注入的方式:有三种
使用构造函数提供。
使用set方法提供。
使用注解提供。
构造函数注入
顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入。具体代码如下:
Set方式注入
顾名思义,就是在类中提供需要注入成员的 set 方法。具体代码如下:
更常用的方式
集合方式注入
顾名思义,就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。
我们这里介绍注入数组,List,Set,Map,Properties。
复杂类型的注入/集合类型的注入
用于给List结构集合注入的标签:
list,array,set
用于个Map结构集合注入的标签:
map,props
代码如下:
User类
public
Person类
public
CollectionDemo类
public
配置文件:
测试类:
/**
* 测试基于xml形式的spring ioc获取对象
*/
4.使用spring的ioc实现账户的CRUD
4.1 基于xml形式
1.引用外部属性文件
2.SPEL表达式
Spring Expression Language,Spring表达式语言,简称SpEL。支持运行时查询并可以操作对象图。
和JSP页面上的EL表达式、Struts2中用到的OGNL表达式一样,SpEL根据JavaBean风格的getXxx()、setXxx()方法定义的属性访问对象图,完全符合我们熟悉的操作习惯。
2.基本语法
SpEL使用#{…}作为定界符,所有在大框号中的字符都将被认为是SpEL表达式。
3.使用字面量
●整数:
●小数:
●科学计数法:
●String类型的字面量可以使用单引号或者双引号作为字符串的定界符号
●Boolean:
4.引用其他bean
5.引用其他bean的属性值作为自己某个属性的值
6.调用非静态方法
7.调用静态方法
8.运算符
①算术运算符:+、-、*、/、%、^
②字符串连接:+
③比较运算符:、==、<=、>=、lt、gt、eq、le、ge
④逻辑运算符:and, or, not, |
⑤三目运算符:判断条件?判断结果为true时的取值:判断结果为false时的取值
⑥正则表达式:matches
代码如下:
配置文件
<?xml version="1.0" encoding="UTF-8"?>
持久层
/*
账户的持久层实现类
*/
业务层
/*
账户的业务层实现类
*/
测试类
public
4.2 xml和注解的混搭
XML配置形式:
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="" init-method="" destroy-method="">
1.用于创建对象的
他们的作用就和在XML配置文件中编写一个标签实现的功能是一样的。
Component:
作用:用于把当前类对象存入spring容器中
属性:
value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
Controller:一般用在表现层
Service:一般用在业务层
Repository:一般用在持久层
以上个注解他们的作用和属性与Component是一模一样。
他们是spring框架为我们提供明确的层使用的注解,使我们的层对象更加清晰。
2.用于注入数据的
他们的作用就和在xml配置文件中的bean标签中写一个标签的作用是一样的。
Autowired:
作用:自动照类型注入。只要容器中唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。
如果ioc容器中没任何bean的类型和要注入的变量类型匹配,则报错。
如果Ioc容器中多个类型匹配时:
出现位置:
可以是变量上,也可以是方法上。
细节:
在使用注解注入时,set方法就不是必须的了。
Qualifier:
作用:在照类中注入的基础之上再照名称注入。在给类成员注入时不能单独使用。但是在给方法参数注入时可以。
属性:
value:用于指定注入bean的id。
Resource:
作用:直接照bean的id注入。它可以独立使用。
属性:
name:用于指定bean的id。
以上注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。
另外,集合类型的注入只能通过XML来实现。
Value:
作用:用于注入基本类型和String类型的数据。
属性:
value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式
SpEL的写法:${表达式}
3.用于改变作用范围的
他们的作用就和在bean标签中使用scope属性实现的功能是一样的。
Scope:
作用:用于指定bean的作用范围。
属性:
value:指定范围的取值。常用取值:singleton prototype
4.和生命周期相关(了解)
他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的。
PreDestroy
作用:用于指定销毁方法。
PostConstruct
作用:用于指定初始化方法。
代码如下:
配置文件
<?xml version="1.0" encoding="UTF-8"?>
持久层
/**
* 账户的持久层实现类
*/
业务层
/**
* 账户的业务层实现类
*/
测试类
public
4.3 纯注解配置
1.注解
该类是一个配置类,它的作用和bean.xml是一样的。
spring中的新注解:
Configuration:
作用:指定当前类是一个配置类。
细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。
ComponentScan:
作用:用于通过注解指定spring在创建容器时要扫描的包。
属性:
value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。
我们使用此注解就等同于在xml中配置了:
Bean:
作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中。
属性:
name:用于指定bean的id。当不写时,默认值是当前方法的名称。
细节:
当我们使用注解配置方法时,如果有方法参数,spring框架会去容器中查找没可用的bean对象。
查找的方式和Autowired注解的作用是一样的。
Import:
作用:用于导入其他的配置类。
属性:
value:用于指定其他配置类的字节码。
当我们使用Import的注解之后,Import注解的类就父配置类,而导入的都是子配置类
PropertySource:
作用:用于指定properties文件的位置。
属性:
value:指定文件的名称和路径。
关键字:classpath,表示类路径下。
2.spring整合junit4
说明:
1、应用程序的入口
main方法
2、junit单元测试中,没有main方法也能执行
junit集成了一个main方法
该方法就会判断当前测试类中哪些方法有 @Test注解
junit就让有Test注解的方法执行
3、junit不会管我们是否采用spring框架
在执行测试方法时,junit根本不知道我们是不是使用了spring框架,
所以也就不会为我们读取配置文件/配置类创建spring核心容器。
4、由以上三点可知
当测试方法执行时,没有Ioc容器,就算写了Autowired注解,也无法实现注入。
使用Junit单元测试:
Spring整合junit的配置:测试我们的配置
1、导入spring整合junit的jar(坐标)
2、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
@Runwith(SpringJUnit4ClassRunner.class)
3、告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置
@ContextConfiguration
参数说明:
locations:指定xml文件的位置,加上classpath关键字,表示在类路径下。
classes:指定注解类所在地位置。
注意:当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上。
代码如下:
配置类
/**
* @author Guohai
* @createTime 2020-07-13 17:14
*/
配置子类
/**
* @author Guohai
* @createTime 2020-07-13 17:16
*/
测试类
RunWith
5.Spring的自动装配
在spring中,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,使用autowire来配置自动装载模式。
在Spring框架xml配置中共有5种自动装配:
(1)no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。
(2)byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。
(3)byType:通过参数的数据类型进行自动装配。
(4)constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。
(5)autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。
最后
大家看完有什么不懂的可以在下方留言讨论,也可以关注我私信问我,我看到后都会回答的。谢谢你的观看,觉得文章对你有帮助的话记得关注我点个赞支持一下!