3.Spring-依赖注入(DI)

Dependency Injection(DI)

依赖注入(Dependency Injection,简称DI)是指通过外部容器在对象之间建立依赖关系的一种方式。

简单说:就是由 IOC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。

与控制反转是同一个概念,或者依赖注入是实现控制反转的一种常见方式。

IOC是一种思想 而依赖注入是 IOC的一种实现。

依赖注入的作用:在容器初始化对象时,把对象的属性进行赋值,处理对象之间的依赖关系

依赖注入

1.设值注入

本质上是调用 类提供的属性的setter方法 进行属性赋值

XML 复制代码
<bean name="user" class="com.rimi.bean.User">
    <property name="username" value="admin"></property>
    <property name="password" value="123456"></property>
</bean>
  • name 代表 属性的名字(因为 spring容器会根据属性名去找对应的setter方法,所以 命名规范)
  • value 代表的属性的值

2.构造注入

本质上是调用 类的 有参的构造方法 进行属性的初始化

XML 复制代码
<bean name="user" class="com.rimi.bean.User">
    <constructor-arg name="username" value="admin"></constructor-arg>
    <constructor-arg name="password" value="123456"></constructor-arg>
    <constructor-arg name="userid" value="1"></constructor-arg>
</bean> 

使用构造注入时,bean中的 constructor-arg 的数目必须和 构造方法中 形参的数目一致

constructor-arg

  • name 代表的是形参的名字
  • value 形参的值
  • index 表示形参的编号
  • type 指定形参的类型。

使用方式:通常以设值注入为主,构造注入为辅。对于依赖关系不需要发生改变的注入,通常使用构造注入。

3.自动装配注入

本质上是调用 类的属性的 byType(类型模式),byName(名称模式)、constructor(构造函数模式),autodetect()进行属性的初始化

XML 复制代码
<bean name="user" autowire="byType"  class="com.rimi.bean.User">
    <property name="username" value="admin"></property>
</bean>
  • no: 不使用自动装配。Bean依赖必须通过ref元素定义。这是默认配置,在较大的部署环境中不鼓励改变这个配置,显式配置合作者能够得到更清晰的依赖关系。
  • byName: 根据setter方法名进行自动装配。Spring容器查找容器中全部Bean,找出其id与setter方法名去掉set前缀,并小写首字母后同名的Bean来完成注入。如果没有找到匹配的Bean实例,则Spring不会进行任何注入。
  • byType: 根据setter方法的形参类型来自动装配。Spring容器查找容器中的全部Bean,如果正好有一个Bean类型与setter方法的形参类型匹配,就自动注入这个Bean;如果找到多个这样的Bean,就抛出一个异常;如果没有找到这样的Bean,则什么都不会发生,setter方法不会被调用。
  • constructor: 与byType类似,区别是用于自动匹配构造器的参数。如果容器不能恰好找到一个与构造器参数类型匹配的Bean,则会抛出一个异常。
  • autodetect: Spring容器根据Bean内部结构,自行决定使用constructor或byType策略。如果找到一个默认的构造函数,那么就会应用byType策略。

4.注解注入

@Autowired
java 复制代码
@Service
public class UserServiceImpl implements UserService{
    @AutoWired
    private UserDao userDao;
}
内部等同于
@Service
public class UserServiceImpl implements UserService{
    @AutoWired(required=true)
    private UserDao userDao;
}
同样也可以指定类型byNmae
@Service
public class UserServiceImpl implements UserService{
    @AutoWired(required=false)
    @Qualifier("userDao")
    private UserDao userDao;
}
@Resource
java 复制代码
@Service
public class UserServiceImpl implements UserService{
    @Resource
    private UserDao userDao;
}
内部等同于
@Service
public class UserServiceImpl implements UserService{
    @Resource(name="userDao")
    private UserDao userDao;
}
同样也可以指定类型byType
@Service
public class UserServiceImpl implements UserService{
    @Resource(type=com.edu.dao.UserDao.class)
    private UserDao userDao;
}  
  • @Resource:用于依赖注入,注入的bean的名字 默认和对应的属性名一样即属性名为userDao @Resource(name="bean名字")来进行注入 使用@Resource进行注入,实现原理反射机制,所以即使属性没有set方法 或者构造方法,依然可以注入成功. 对于@Resource注解,如果没有指定注入的bean的名字,并且存在两个相同接口(类型)的bean,则会抛出异常。
  • @Autowired:用于依赖注入,默认以byType进行自动装配,当Spring容器中有 相同类型的bean的时候,会自动的注入到私有属性,如果容器里存在两个相同接口(类型的)bean 则会抛出异常
@autowired和@resource注解的区别?
  • @Autowired与@Resource都可以用来装配bean,都可以写在字段或setter方法上
  • @Autowired默认按类型装配,默认情况下必须要求依赖对象存在,如果要允许null值,可以设置它的required属性为false。如果想使用名称装配可以结合@Qualifier注解进行使用。
  • @Resource,默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行名称查找。如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

推荐使用@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与Spring的耦合。

相关推荐
Ivanqhz1 分钟前
linearize:控制流图(CFG)转换为线性指令序列
开发语言·c++·后端·算法·rust
一直都在5723 分钟前
Java线程池
java·开发语言
掘金者阿豪7 分钟前
从聊天入口到系统治理:深度解读“小龙虾 Web / OpenClaw”左侧导航的产品设计逻辑
后端
二闹9 分钟前
变量世界的“通行证”:理解Python中的global与nonlocal
后端·python
亚马逊云开发者10 分钟前
article
java·开发语言
集智飞行11 分钟前
安装rust和cargo
开发语言·后端·rust
云烟成雨TD14 分钟前
Spring AI 1.x 系列【11】基于 PromptTemplate 构建一站式 AI 写作助手
java·人工智能·spring
清汤饺子14 分钟前
搞懂 Cursor 后,我一行代码都不敲了《进阶篇》
前端·javascript·后端
我叫黑大帅17 分钟前
Gin 实战入门:从环境搭建到企业级常用特性全解析
后端·面试·go
qqacj18 分钟前
SpringBoot Test详解
spring boot·后端·log4j