Spring 依赖注入概念和三种注入方式(理解及应用)

什么是注入

  • 要了解Spring的三种注入方式首先前提是得先了解一下什么是注入,相信很多人对这个概念都是模糊不清的,网上的解释是这样的:
    依赖注入(Dependency Injection)和控制反转(Inversion of Control,Spring IOC说的就是这个东西)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。

  • 我来大概解释一下上面的意思,举个例子:
    传统程序里:比如现在存在一个A类,和一个B类,当A类想要使用B类的时候 我们是不是要在A类的方法里主动的去做 B b=new B()这么一个事情?这时的小b就是一个实例,在A类这个方法在执行的时候 A类就属于上面说的调用者, B类就属于 被调用者 这个过程在执行的时候是A主动去创建出B来的。
    在Spring里:你只需要在xml配置文件里配置好B类的Bean配置,然后Spring工厂会在程序启动自动将你在配置文件里的B类的Bean帮你创建出来了一个实例(默认是一个,这就是单例),也就是帮忙将上面传统程序中在A类中主动去创建B类这个过程帮你做了,当我们想在A类中去使用B类,只需要将B类注入就可以使用了,而且在Spring里,假如还存在一个C类想要用B类,只要C类也将B类注入就好,就是Spring工厂创建出来的B类的实例大家都可以用,大概就是这么个意思。

  • 依赖注入的概念总结:
    上面讲到Bean这个东西,可能看到这里有些人对Bean又有疑惑了,在这里我就大概扩展一下,其实Bean这个东西初学者可以直接把它作为是一个普通的Java类去理解它就好。
    这些过程我们是在代码里面看不到的过程,可能在写代码上看起来感觉没什么区别,但是背地里它们做的事情就是这么的不一样,这就是控制反转,依赖注入。

三种注入方式

Spring的三种注入方式,分别是构造方法注入,setter注入,基于注解的注入。
(有两种实现的方式:1.写XML配置bean,2.Spring的注解@Component,第二种方式是现在普遍都在用的,Spring提供了注解的方式,避免了频繁编写配置XML,简单好用)

  • 我这里用两个类作为示例,Person类和Car类,现在我要在Person类里去调用Car类(对应了上面我写的A类去调用B类一样,Person类相当于A类,Car类相当于B类),先使用XML配置给大家讲解

XML配置文件的注入

  • 1.构造方法注入
    Person类:
package com.chenjl.yamlPratice;public class Person {private Car  car;//车类public Person(Car car) {this.car=car;}public void goDrive(){car.drive();}
}

Car类

package com.chenjl.yamlPratice;public class Car {private String carName;public void drive(){//这是Car类中的一个叫drive的方法System.out.println("开车中。。。。");}
}
<!--注册实体Person类,id就是实例的命名:person-->
<bean id="person" class="com.chenjl.yamlPratice.Person"><constructor-arg ref="car"></constructor-arg><!-- constructor-arg 这个翻译过来是 构造参数的意思 ref的值就是下面那个bean的id的值-->
</bean>
<!--注册实体Car类,id就是实例的命名:car-->
<bean id="car" class="com.chenjl.yamlPratice.Car"></bean>
  • 友情提示:如果不懂XML文件里bean标签配置的各个属性的可以百度查一下写法
  • 这里第二个Car这个bean被配置到第一个person这个bean的构造参数里了。这里配置完就已经把Car这个类已经注入到Person这个类了,如果要在一个类的构造方法的参数里有多个如下代码,也就是要在一个类里注入多个类,那么我们只要在配置文件里像这样写就好,加一个name属性去区分它
package com.chenjl.yamlPratice;public class Person {private Car  car;//车类pricate Bus bus;//公交车类public Person(Car car,Bus bus) {this.car=car;this.bus=bus;}public void goDrive(){car.drive();}
}
package com.chenjl.yamlPratice;public class Bus{private String busName;public void driveBus(){//这是Car类中的一个叫drive的方法System.out.println("开公交车。。。。");}
}
<!--注册实体Person类,id就是实例的命名:person-->
<bean id="person" class="com.chenjl.yamlPratice.Person"><constructor-arg name="car" ref="car"></constructor-arg><!-- constructor-arg 这个翻译过来是 构造参数的意思 ref的值就是下面那个bean的id的值--><constructor-arg name="bus" ref="bus"></constructor-arg><!-- constructor-arg 这个翻译过来是 构造参数的意思 ref的值就是下面那个bean的id的值-->
</bean>
<!--注册实体Car类,id就是实例的命名:car-->
<bean id="car" class="com.chenjl.yamlPratice.Car"></bean>
<!--注册实体Bus类,id就是实例的命名:bus-->
<bean id="bus" class="com.chenjl.yamlPratice.Bus"></bean>

配置文件里的constructor-arg标签顺序和构造参数的里面顺序没有影响的,这个就是XML写法的构造参数注入。

  • 2.Setter方法注入
package com.chenjl.yamlPratice;public class Person {private Car  car;public Person(Car car) {this.car=car;}public Person() {//无参数构造方法}public Car getCar() {//get方法return car;}public void setCar(Car car) {//set方法this.car = car;}public void goDrive(){car.drive();}
}

这个是我在上面的Person类的基础上加了它的get和set还有无参构造方法,这时候我们的XML文件就可以这样去配置注入啦

<bean id="person" class="com.chenjl.yamlPratice.Person"><property name="car" ref="car"></property><!-- property属性 spring会将name值的每个单词首字母转换成大写,然后再在前面拼接上”set”构成一个方法名,然后去对应的类中查找该方法,通过反射调用,实现注入。 -->
</bean><bean id="car" class="com.chenjl.yamlPratice.Car"></bean>
</beans>

注意:spring会将name值的每个单词首字母转换成大写,然后再在前面拼接上”set”构成一个方法名,然后去对应的类中查找该方法,通过反射调用,实现注入。
还有一点需要注意:如果通过set方法注入属性,那么spring会通过默认的空参构造方法来实例化对象,所以如果在类中写了一个带有参数的构造方法,一定要把空参数的构造方法写上,否则spring没有办法实例化对象,导致报错。

基于Spring注解的注入

  • 3.基于注解的注入
    在介绍注解注入的方式前,先简单了解bean的一个属性autowire,autowire主要有三个属性值:constructor,byName,byType。

constructor:通过构造方法进行自动注入,spring会匹配与构造方法参数类型一致的bean进行注入,如果有一个多参数的构造方法,一个只有一个参数的构造方法,在容器中查找到多个匹配多参数构造方法的bean,那么spring会优先将bean注入到多参数的构造方法中。

byName:被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写,这一点与手动set注入有点不同。

byType:查找所有的set方法,将符合符合参数类型的bean注入。
注解方式注册bean,注入依赖

主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有所差异:

@Component:可以用于注册所有bean
@Repository:主要用于注册dao层的bean
@Controller:主要用于注册控制层的bean
@Service:主要用于注册服务层的bean
这四个注解功能都是一样的,只是为了分层表示

要先在xml文件里配置这个开启Spring注解,并且指定这个注解生效的包的位置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--开启注解的支持--><context:annotation-config/><!--指定要扫描的包,这个包下的注解会生效--><context:component-scan base-package="com.chenjl.yamlPratice"/>
</beans>
@Component("person")//在这个类的上面加上这个注解相当与xml配置的这句话:<bean id="person" class="com.chenjl.yamlPratice.Person"> 括号里的person其实就跟 bean标签里的id是一个作用,这里其实可以不写这个person的,不写Spring会默认以当前类的首字母小写作为id是一个意思
public class Person {@Autowired //使用@Autowired 标签实现注入private Car  car;public Person(Car car) {this.car=car;}public Person() {//无参数构造方法}public Car getCar() {//get方法return car;}public void setCar(Car car) {//set方法this.car = car;}public void goDrive(){car.drive();}
}
@Component//在这个类的上面加上这个注解相当与xml配置的这句话:<bean id="car" class="com.chenjl.yamlPratice.Car"></bean>
public class Car {private String carName;public void drive(){//这是Car类中的一个叫drive的方法System.out.println("开车中。。。。");}
}

这个就是实现了注解的注入,说一下这个@Autowired的作用
@Autowired
作用:自动按照类型注入
1)IoC容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
2)IoC容器中没有任何bean对象的类型和要注入的变量类型匹配,则报错
3)IoC容器中有多个bean对象类型和要注入的变量类型匹配,首先查看是否有变量名称与bean对象id一致的bean对象,如果有则注入,没有则报错
出现位置:可以是变量上,也可以是方法上
细节:在使用注解注入时,set方法就不是必须的了

@Resource这个注解和@Autowired的作用差不多

总结

其实现在项目中,一般都是一个接口对应一个接口实现类,只要在对应的实现类上加上对于的层的注解或者直接使用@Component注解也可以去注册它成为一个Spring的组件,然后在对应要调用的类里去使用@Autowired注解去注入去使用就好。全文纯属个人理解,如有不对的地方欢迎可以留言一起探讨~

Spring 依赖注入的理解及三种注入方式相关推荐

  1. spring注解之@Import注解的三种使用方式

    1.@Import注解须知 1.@Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中 2.加入IOC容器的方式有很多种,@Import注解就相对很牛皮 ...

  2. spring入门之Spring 常用的三种注入方式

    Spring 常用的三种注入方式 Spring 通过 DI(依赖注入)实现 IOC(控制反转),常用的注入方式主要有三种:构造方法注入,set 方法注入,基于注解的注入. 一.通过构造方法注入 先简单 ...

  3. 扯一把 Spring 的三种注入方式,到底哪种注入方式最佳?

    循环依赖这个问题,按理说我们在日常的程序设计中应该避免,其实这个本来也是能够避免的.不过由于总总原因,我们可能还是会遇到一些循环依赖的问题,特别是在面试的过程中,面试考察循环依赖,主要是想考察候选人对 ...

  4. Spring 的三种注入方式?

    1. 实例的注入方式 首先来看看 Spring 中的实例该如何注入,总结起来,无非三种: 属性注入 set 方法注入 构造方法注入 我们分别来看下. 1.1 属性注入 属性注入是大家最为常见也是使用最 ...

  5. Spring 的三种注入方式,到底哪种注入方式最佳?

    1. 实例的注入方式 首先来看看 Spring 中的实例该如何注入,总结起来,无非三种: 属性注入 set 方法注入 构造方法注入 我们分别来看下. 1.1 属性注入 属性注入是大家最为常见也是使用最 ...

  6. spring三种注入方式

    设置Spring的作用域 或者使用枚举值设置 单例和多里使用场景 自动注入 @Primary 一个接口有多个实现被spring管理吗,在依赖注入式,spring会不知道注入哪个实现类就会抛出NoUni ...

  7. Spring的三种注入方式(为什么推荐构造器注入?)

    Spring的三种注入方式 一.属性注入 @Resource和@Autowired的区别 为什么尽量使用 @Resource? 二.setter 注入 三.构造器注入 具体可以看看Spring官网 为 ...

  8. Spring Boot项目(Maven\Gradle)三种启动方式及后台运行详解

    Spring Boot项目三种启动方式及后台运行详解 1 Spring Boot项目三种启动方法 运行Application.java类中的Main方法 项目管理工具启动 Maven项目:mvn sp ...

  9. Spring Boot 启动执行某个方法的三种实现方式

    Spring Boot 启动执行某个方法的三种实现方式 Spring Boot 启动执行某个方法的三种实现方式 第一种方式 @PostConstruct 注解解释 具体实现 第二种方式 Applica ...

最新文章

  1. python读取输入流_python – 将一个正在运行的程序的输出流传输到其他正在运行的程序的输入流...
  2. Java基础day9
  3. 使用jQuery OCUpload实现excel文件一键上传功能
  4. 使用SAP API portal进行SAP SuccessFactors的API测试
  5. java cpu 内存使用情况_java高cpu占用和高内存占用问题排查 (转)
  6. 和付费网盘说再见,自己起个网盘不香吗?| Java 开源项目
  7. java对日期进行排序_Java对日期时间值的集合进行排序
  8. 更改Tomcat默认目录+端口+设置缺省网页的方法
  9. 23andme、gsa、wegene各染色体位点统计
  10. Android音视频三-AndroidStudio整合FFmpeg项目+FFmpeg视频解码
  11. python爬虫实例1:获取一个网页的列表数据
  12. linux下usb 驱动
  13. swift生成二维码
  14. 计算机课程教改论文,关于计算机基础课程教学改革论文(2)
  15. 转:浅谈Radius协议 -来自CSDN:http://blog.csdn.net/wangpengqi/article/details/17097221
  16. MessageBox弹框写删除功能
  17. 基于MATLAB二分法求解一元二次方程的根
  18. Python Pandas DataFrame 表格 打印输出不能对齐的两种解决方案
  19. 用飞信批量加好友——解放鼠标,更解放你的手!
  20. GK2A 火点提取运行需要要的包安装

热门文章

  1. Python二级应用题代码自用(无忧二级)
  2. Video标签播放视频(动态视频URL)
  3. Why So Serious
  4. 字符设备驱动基础-linux驱动开发第2部分-朱有鹏-专题视频课程
  5. 1、R5为ISP,只能进行ip地址配置:其所有接口配置为公有ip地切 2、R1与R5间使用PPP的PAP认证,R5为主认证方;R2与R5间使用PPP的chap认证 R5为主认证方;R3与R5间使用H
  6. 2021年计算机专业工作规划,2021最新计算机课教学计划
  7. 一步一步教你VMWare安装苹果Mac OS X
  8. oracle对应字符集汇总,Oracle字符集子集与超级的对应关系
  9. 云平台架构知识点总结
  10. Java怎么弹出cmd命令窗口_怎么在java里打开bat文件,并打开cmd窗口执行,举例一个完整代码。...