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的耦合。

相关推荐
HelloWord~5 分钟前
SpringSecurity+vue通用权限系统2
java·vue.js
让我上个超影吧6 分钟前
黑马点评【基于redis实现共享session登录】
java·redis
00后程序员23 分钟前
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
后端
HyggeBest28 分钟前
Mysql的数据存储结构
后端·架构
TobyMint1 小时前
golang 实现雪花算法
后端
G探险者1 小时前
【案例解析】一次 TIME_WAIT 导致 TPS 断崖式下降的排查与优化
后端
BillKu1 小时前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
全栈凯哥1 小时前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表
chxii1 小时前
12.7Swing控件6 JList
java
全栈凯哥1 小时前
Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解
java·算法·leetcode·链表