目录
Bean对象注入
也就是DI(依赖注入):将某个对象需要的依赖注入到属性中,常见的对象注入方法有属性注入、构造方法注入、Setter注入
属性注入
属性注入是通过@Autowired注解实现的,将Service类注入到Controller类中
代码示例
User类
package org.example.model;
import lombok.Data;
@Data
public class User {
private String userName;
private Integer id;
}
Service类
模拟根据id获取用户信息的操作
package org.example.service;
import org.example.model.User;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public User getUser(Integer id) {
User user = new User();
user.setId(id);
user.setUserName("Java-" + id);
return user;
}
}
Controller类
通过@Autowired注解将容器中的bean对象注入到属性
package org.example.controller;
import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
//属性注入
@Autowired
private UserService userService;
public User getUser(Integer id) {
return userService.getUser(id);
}
}
启动类
public class APP {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext("org.example");
UserController userController = context.getBean(UserController.class);
System.out.println(userController.getUser(1));
}
}
构造方法注入
构造方法注入是在类的构造方法中实现注入
package org.example.controller;
import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController2 {
private UserService userService;
@Autowired
public UserController2(UserService userService) {
this.userService = userService;
}
// public UserController2() {
//
// }
public User getUser(Integer id) {
return userService.getUser(id);
}
}
User类、Service类以及启动类都与上述类似,此时就成功通过构造方法注入Bean对象。当Controller类中只有一个构造方法时,可以省略@Autowired注解,如果有多个构造方法,就必须添加上@Autowired来指定具体是使用哪个构造方法,否则就会出现如下报错
Setter注入
Setter注入和属性的Setter方法实现类似,只不过在设置set方法的时候需要加上@Autowired注解
package org.example.controller;
import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController3 {
//Setter注入
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public User getUser(Integer id) {
return userService.getUser(id);
}
}
注意:使用构造方法进行属性注入时,当类中只有一个构造方法时可以省略@Autowired注解,但是使用Setter进行属性构造时,不能省去@Autwired注解
三种注入方式优缺点
· 属性注入的优点是简洁,使用方便;缺点是只能用于IoC容器,如果是非IoC容器不可用,并且在使用时会出现空指针异常
· 构造方法注入是Spring推荐的注入方式,他的缺点是如果多个注入会显得比较臃肿,但出现这种情况应该考虑一下是否符合程序的单一职责的设计模式,它的优点是通用性,在使用之前一定要保证注入的类不为空
· Setter 方式是 Spring 前期版本推荐的注入方式,但通用性不如构造方法,所有 Spring 现版本已经推荐使用构造方法注入的方式来进行类注入了。
@Resource注解
在进行类注入时除了使用@Autowired外还可以使用@Resource进行注入
package org.example.controller;
import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController {
//属性注入
//@Autowired
@Resource
private UserService userService;
public User getUser(Integer id) {
return userService.getUser(id);
}
}
@Autowired与@Resource的区别
· @Autowired是Spring的注解,而@Resource收JDK的注解
· 使用时设置的参数不同,相比于@Autowired,@Resource支持更多的参数设置,例如name设置,设置之后就可以根据name的值来获取Bean
同一类型多个Bean问题的解决
@Configuration
public class AppConfig {
//方法上使用Bean注解表示注册一个Bean对象到容器中
//方法的名称,就是bean ID(名称),方法的返回值就是注册的实例对象
//一般是public修饰的实例方法
@Bean
public User testBean1() {
User user = new User();
user.setUserName("testBean1");
return user;
}
@Bean
public User testBean2() {
User user = new User();
user.setUserName("testBean1");
return user;
}
}
@Controller
public class UserController {
@Autowired
private User user;
}
当遇到上述问题时,有三种解决方式
①变量名=bean的id(名称)
@Controller
public class UserController {
@Autowired
private User testBean1;
}
②使用@Resource(name="xxx")
@Controller
public class UserController {
@Resource(name = "testBean1")
private User user;
}
③使用@Qualifier
@Controller
public class UserController {
@Autowired
@Qualifier("testBean2")
private User user1;
}