Spring IOC 自动装配(@Autowired和@Resource)

Spring IOC 自动装配(注入)

Spring IOC 自动装配(注入)

注解⽅式注⼊ Bean

对于 bean 的注⼊,除了使⽤ xml 配置以外,可以使⽤注解配置。注解的配置,可以简化配置⽂件,提⾼开发的速度,使程序看上去更简洁。
对于注解的解释,Spring对于注解有专⻔的解释器,对定义的 注解进⾏解析,实现对应bean对象的注⼊。通过反射技术实现。

准备环境

1、修改配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 https://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd">

2、开启自动化注入

<!--开启⾃动化装配(注⼊)-->
<context:annotation-config/>
<bean id="userDao" class="com.xxxx.dao.UserDao"></bean>
<bean id="userService" class="com.xxxx.service.UserService"></bean>

3、给注入的bean对象添加注解

@Resource注解

@Resource注解实现⾃动注⼊(反射)

  • 默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)
  • 如果属性字段名称未找到,则会通过类型(Class类型)查找
  • 属性可以提供set方法,也可以不提供set方法
  • 注解可以声明在属性级别 或 set方法级别
  • 可以设置name属性,name属性值必须与bean标签的id属性值⼀致;如果设置了name属性值,就只会按照name属性值查找bean对象
  • 当注入接口时,如果接口只有⼀个实现则正常实例化;如果接口存在多个实现,则需要使用name属性指定需要被实例化的bean对象

注意:JDK11无法在Spring中使用@Resource注解

JDK11将javax.annotation这个包移除了,所以可以通过maven或者其他方式导入。如果这个依赖无法使用,可以去MVN上自行查找。

<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

代码示例:
1、默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)

/**
* @Resource注解实现⾃动注⼊(反射)
* 默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)
*/
public class UserService {
@Resource
 private UserDao userDao; // 属性字段的名称与bean标签的id属性值相等
 public void setUserDao(UserDao userDao) {
 this.userDao = userDao;
 }
 public void test() {
 // 调⽤UserDao的⽅法
 userDao.test();
 }
}

2、 如果属性字段名称未找到,则会通过类型(Class类型)查找

/**
* @Resource注解实现⾃动注⼊(反射)
* 如果属性字段名称未找到,则会通过类型(Class类型)查找
*/
public class UserService {
 @Resource
 private UserDao ud; // 当在配置⽂件中属性字段名(ud)未找到,则会查找对应的
class(UserDao类型)
 public void setUd(UserDao ud) {
 this.ud = ud;
 }
 public void test() {
 // 调⽤UserDao的⽅法
 ud.test();
 }
}

3、 属性可以提供set⽅法,也可以不提供set⽅法

/**
* @Resource注解实现⾃动注⼊(反射)
* 属性可以提供set⽅法,也可以不提供set⽅法
*/
public class UserService {
 @Resource
 private UserDao userDao; // 不提供set⽅法
 public void test() {
 // 调⽤UserDao的⽅法
 userDao.test();
 }
}

4、注解可以声明在属性级别 或 set⽅法级别

/**
* @Resource注解实现⾃动注⼊(反射)
* 注解可以声明在属性级别 或 set⽅法级别
*/
public class UserService {
 private UserDao userDao;
 @Resource // 注解也可设置在set⽅法上
 public void setUserDao(UserDao userDao) {
 this.userDao = userDao;
 }
 public void test() {
 // 调⽤UserDao的⽅法
 userDao.test();
 }
}

5、 可以设置name属性,name属性值必须与bean标签的id属性值⼀致;如果设置了name属性值,就只会按照name属性值查找bean对象

/**
* @Resource注解实现⾃动注⼊(反射)
* 可以设置name属性,name属性值必须与bean的id属性值⼀致;
* 如果设置了name属性值,就只会按照name属性值查找bean对象
*/
public class UserService {
 @Resource(name = "userDao") // name属性值与配置⽂件中bean标签的id属性值⼀致
 private UserDao ud;
 public void test() {
 // 调⽤UserDao的⽅法
 ud.test();
 }
}

6、 当注⼊接⼝时,如果接⼝只有⼀个实现则正常实例化;如果接⼝存在多个实现,则需要使⽤name属性指定需要被实例化的bean对象
定义接⼝类 IUserDao.java
package com.xxxx.dao;

/**
* 定义接⼝类
*/
public interface IUserDao {
 public void test();
}

定义接⼝实现类 UserDao01.java

package com.xxxx.dao;
/**
* 接⼝实现类
*/
public class UserDao01 implements IUserDao {
 @Override
 public void test(){
 System.out.println("UserDao01...");
 }
}

定义接⼝实现类 UserDao02.java

package com.xxxx.dao;
/**
* 接⼝实现类
*/
public class UserDao02 implements IUserDao {
 @Override
 public void test(){
 System.out.println("UserDao02...");
 }
}

XML配置⽂件

<!--开启⾃动化装配(注⼊)-->
<context:annotation-config/>
<bean id="userService" class="com.xxxx.service.UserService"></bean>
<bean id="userDao01" class="com.xxxx.dao.UserDao01"></bean>
<bean id="userDao02" class="com.xxxx.dao.UserDao01"></bean>

使⽤注解 UserService.java

/**
* @Resource注解实现⾃动注⼊(反射)
* 当注⼊接⼝时,如果接⼝只有⼀个实现则正常实例化;如果接⼝存在多个实现,则需要使⽤
name属性指定需要被实例化的bean对象
*/
public class UserService {
 @Resource(name = "userDao01") // name属性值与其中⼀个实现类的bean标签的id属
性值⼀致
 private IUserDao iUserDao; // 注⼊接⼝(接⼝存在多个实现)
 public void test() {
 iUserDao.test();
 }
}

@Autowired注解

@Autowired注解实现自动化注入:

  • 默认通过类型(Class类型)查找bean对象 与属性字段的名称无关
  • 属性可以提供set方法,也可以不提供set方法
  • 注解可以声明在属性级别 或 set方法级别
  • 可以添加@Qualifier结合使用,通过value属性值查找bean对象(value属性值必须要设置,且值要与bean标签的id属性值对应)

1、默认通过类型(Class类型)查找bean对象 与属性字段的名称⽆关

/**
* @Autowired注解实现⾃动化注⼊
* 默认通过类型(Class类型)查找bean对象 与属性字段的名称⽆关
*/
public class UserService {
 @Autowired
 private UserDao userDao; // 默认通过类型(Class类型)查找bean对象 与属性字段
的名称⽆关
public void setUserDao(UserDao userDao) {
 this.userDao = userDao;
 }
 public void test() {
 // 调⽤UserDao的⽅法
 userDao.test();
 }
}

2、属性可以提供set⽅法,也可以不提供set⽅法

/**
* @Autowired注解实现⾃动化注⼊
* 属性可以提供set⽅法,也可以不提供set⽅法
*/
public class UserService {
 @Autowired
 private UserDao userDao; // 不提供set⽅法
 public void test() {
 // 调⽤UserDao的⽅法
 userDao.test();
 }
}

3、 注解可以声明在属性级别 或 set⽅法级别

/**
* @Autowired注解实现⾃动化注⼊
* 注解可以声明在属性级别 或 set⽅法级别
*/
public class UserService {
 private UserDao userDao;
 @Autowired// 注解可以声明在set⽅法级别
 public void setUserDao(UserDao userDao) {
 this.userDao = userDao;
 }
 public void test() {
 // 调⽤UserDao的⽅法
 userDao.test();
 }
}

4、可以添加@Qualifier结合使⽤,通过value属性值查找bean对象(value属性值必须要设置,且值要与bean标签的id属性值对应)

/**
* @Autowired注解实现⾃动化注⼊
* 可以添加@Qualifier结合使⽤,通过value属性值查找bean对象
 value属性值必须要设置,且值要与bean标签的id属性值对应
*/
public class UserService {
 @Autowired
 @Qualifier(value="userDao") // value属性值必须要设置,且值要与bean标签的id属
性值对应
 private UserDao userDao;
 public void test() {
 userDao.test();
 }
}

总结:
推荐使⽤@Resource 注解是属于J2EE的,减少了与Spring的耦合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值