Spring IOC 自动注入
注解方式注入Bean
对于bean的注入,除了使用xml配置以外,可以使用注解配置。注解的配置,可以简化配置文件,提高开发的速度,使程序看上去更简洁。
对于注解的解释,Spring对于注解有专门的解释器,对于定义的注解进行解析,实现对应bean对象的注入。通过反射技术实现。
准备环境
1.修改配置文件
2.开启自动化注入
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!--准备SpringIOC自动注入-->
<!--
1.准备环境
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
2.开启自动注入
<context:annotation-config/>
-->
<!--开启⾃动化装配(注⼊)-->
<context:annotation-config/>
<!--实例化bean对象-->
<!--所有需要实例化的bean对象都要在配置文件中设置-->
<bean id="userDao" class="com.xxxx.dao.UserDao"/>
<bean id="userService" class="com.xxxx.service.UserService"/>
</beans>
@Resource注解
@Resource注解实现自动注入(反射)
- 默认根据属性字段名称查找对应的 bean 对象 (属性字段的名称与bean标签的id属性值相等)
- 如果属性字段名称未找到,则会通过类型(Class类型)查找
- 属性可以提供set方法,也可以不提供set方法
- 注解可以声明在属性级别 或 set方法级别
- 可以设置name属性,name属性值必须与bean标签的id属性值⼀致;如果设置了name属性值,就只会按照name属性值查找bean对象
- 当注⼊接⼝时,如果接⼝只有⼀个实现则正常实例化;如果接⼝存在多个实现,则需要使⽤name属性指定需要被实例化的bean对象
代码示例:
1.根据属性字段名查找bean对象
/**
* @Resource注解实现⾃动注⼊(反射)
* 默认根据属性字段名称查找对应的bean对象 (属性字段的名称与bean标签的id属性值相等)
*/
public class UserService {
//直接将注解声明在字段上
@Resource
private UserDao userDao;
public void test(){
System.out.println("UserService...");
//调用UserDao的方法
userDao.test();
}
}
2.通过类型(Class类型)查找
/**
* @Resource注解实现⾃动注⼊(反射)
* 如果属性字段名称未找到,则会通过类型(Class类型)查找
*/
public class UserService {
//直接将注解声明在字段上
@Resource
private UserDao ud;//当在配置文件中属性字段名(ud)未找到,则会查找对应的class(UserDao类型)
public void test(){
System.out.println("UserService...");
//调用UserDao的方法
ud.test();
}
}
3.提供set方法
/**
* @Resource注解实现⾃动注⼊(反射)
* 属性可以提供set⽅法,也可以不提供set⽅法
*/
public class UserService {
//直接将注解声明在字段上
@Resource
private UserDao userDao;
//提供set方法
public void setUd(UserDao userDao) {
this.userDao = userDao;
}
public void test(){
System.out.println("UserService...");
//调用UserDao的方法
userDao.test();
}
}
4.注解可以声明在属性级别或set方法级别
/**
* @Resource注解实现⾃动注⼊(反射)
* 注解可以声明在属性级别 或 set⽅法级别
*/
public class UserService {
private UserDao userDao;
//提供set方法
@Resource // 注解也可设置在set⽅法上
public void setUd(UserDao userDao) {
this.userDao = userDao;
}
public void test(){
System.out.println("UserService...");
//调用UserDao的方法
userDao.test();
}
}
5.可以设置name属性
/**
* @Resource注解实现⾃动注⼊(反射)
* 可以设置name属性,name属性值必须与bean的id属性值⼀致;
* 如果设置了name属性值,就只会按照name属性值查找bean对象
*/
public class UserService {
@Resource(name = "userDao") // name属性值与配置⽂件中bean标签的id属性值⼀致
private UserDao ud;
public void test(){
System.out.println("UserService...");
//调用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 = "userDao1") // name属性值与其中⼀个实现类的bean标签的id属性值⼀致
private IUserDao iUserDao;//注入接口(接口存在多个实现)
public void test(){
System.out.println("UserService...");
iUserDao.test();
}
}
@Autowired注解
@Autowired注解实现自动化注入:
- 默认通过类型(Class类型)查找bean对象 与属性字段的名称⽆关
- 属性可以提供set方法,也可以不提供set方法
- 注解可以声明在属性级别 或 set方法级别
- 可以添加@Qualifier结合使⽤,通过value属性值查找bean对象(value属性值必须要设置,且值要与bean标签的id属性值对应)
1.通过类型(Class类型)查找bean对象
默认通过类型(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结合使⽤
可以添加@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();
}
}