文章目录
- 1. 对象注入
- 1.2 属性注入
- 1.2.1 属性注入的优缺点
- 1.3 Setter方法注入
- 1.3.1 Setter注入的优缺点
- 1.4 构造方法注入(官方推荐)
- 1.4.1 构造方法的优缺点
- 1.5 @Resource与@Autowired区别
1. 对象注入
获取Bean对象也称为对象注入/对象装配,表示把某个对象从Spring容器中取出来给某个类。
对象注入的方法有三种:
- 属性注入
- Setter注入
- 构造方法注入
1.2 属性注入
属性注入是用一个叫
@Autowired
注解实现的,当spring运行时,会将实现@Autowired
注解的属性自动获取一个对象。
下述代码展示:将Service类注入到Controller类中。
- Service代码:
import org.springframework.stereotype.Service;
@Service
public class UserService {
/**
* 注意:此处是伪代码,用来代替数据库 实际中是不用new对象的
* @param id 根据Id获取用户信息
* @return 返回一个对象存储到Spring容器中
*/
public User getUser(Integer id){
User user = new User();
user.setName("lisi");
user.setAge(18);
user.setId(1);
return user;
}
}
- Controller代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
//使用注解 自动获取spring容器中的Bean对象/对象注入
@Autowired
private UserService userService;
public User getUser(Integer id){
return userService.getUser(id);
}
}
在Controller类中使用
@Autowired
注解时,对象引用名建议首字母小写,合规;因为在获取对象时是按照UserService这个类搜索,再按照userService这个名字获取的,这个命名规则是spring规定的;
- 测试是否拿到了Service类:成功拿到了
public class App {
public static void main(String[] args) {
//1.得到spring
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//2.获得bean
UserController userController = context.getBean("userController",UserController.class);
//验证是否获取到Bean对象
System.out.println(userController.getUser(1).toString());
}
}
1.2.1 属性注入的优缺点
优点:简单粗暴
缺点:
1. 没办法实现final修饰的变量注入。 2. 兼容性差,只适用于IoC容器 3. 由于使用简单,更容易违反单一设计原则(单一设计原则:一个类一个功能)
1.3 Setter方法注入
Service类代码和测试类代码不变,变更Controller代码:
@Controller
public class UserController {
private UserService userService;
/*
在set方法上添加@Autowired注解,spring容器会自动把Bean对象传过来
*/
@Autowired
public void setUserService(UserService userService){
this.userService = userService;
}
public User getUser(Integer id){
return userService.getUser(id);
}
}
- 调用测试类验证:
1.3.1 Setter注入的优缺点
优点:由于set方法只会传入一个参数,所以更符合单一设计原则
缺点:
1. 不能注入final不可变对象 2. 使用Setter注入的对象可能会被修改;因为在set方法进行注入后,可以在任何地方new一个UserController对象调用setUserService修改userService的引用。
1.4 构造方法注入(官方推荐)
Service类代码和测试类代码不变,变更Controller代码:
@Controller
public class UserController {
private UserService userService;
/*
当只有一个构造方法时,可以省略@Autowired
一样可以完成对象注入
*/
public UserController(UserService userService) {
this.userService = userService;
}
}
当只有一个构造方法时,可以省略@Autowired,但是有多个构造方法时不能省略@Autowired。
- 调用测试类:
为什么构造方法可以省略注解?那是因为这是官方推荐的,自然要大力支持啦。就好像HashMap与HashTable,HashMap可以允许key-value是null,但是HashTable就不能,因为HashTable底层可能是数组加链表实现的,需要根据key值来计算位置的,HashMap源码中写了null值的处理,为null转换成0,而HashTable并没有进行特别处理,只能报错。
1.4.1 构造方法的优缺点
优点:
- 可以注入final不可变对象(因为被final修饰的对象的初始化要么在定义时进行赋值,要么在构造方法中赋值)
- 注入的对象不会被改变(构造方法只能执行一次)
- 构造方法可以保证注入的对象完全被初始化(在类加载的初始化阶段就会执行构造方法,之后再把类注入到spring容器中)
- 兼容性好(构造方法是所有框架都支持的)
缺点:无
1.5 @Resource与@Autowired区别
使用@Resource注解进行对象注入,可以看到@Resource注解不能用于构造方法上。
- 使用@Resource注解成功获取对象:
@Resource与@Autowired区别:
@Resource是来自JDK,@Autowired来自spring官方
@Resource的注入能力弱于@Autowired,只能用于属性注入和set方法注入,@Autowired可以用于属性注入、set方法注入以及构造方法注入
@Resource提供的参数更多,@Autowired只有一个required参数,这就导致如果同一个类
被注入多个到spring容器中,使用@Autowired就不行,使用@Resource的来设置name属性。
- @Resource提供的参数:
- @Autowired提供的参数:
,@Autowired只有一个required参数,这就导致如果同一个类
被注入多个到spring容器中,使用@Autowired就不行,使用@Resource的来设置name属性。
- @Resource提供的参数:
- @Autowired提供的参数: