0


「JavaEE」Spring IoC:依赖注入

依赖注入描述的是一个过程,指的是 IoC 容器在创建 Bean 时, 提供运行时所依赖的对象

通俗来讲就是把对象取出来放到某个类的属性中

Spring 提供了三种依赖注入的方式:

  1. 属性注入(Field Injection)
  2. 构造方法注入(Constructor Injection)
  3. Setter 注入(Setter Injection)

下面我们使用这三种方式分别将 Service 类注入到 Controller 类中


属性注入

使用 **

  1. @Autowired

** 实现(autowire 意为自动装配)

  1. @Controller
  2. public class UserController {
  3. @Autowired
  4. private UserService userService;
  5. public void hello() {
  6. System.out.println("UserController...");
  7. userService.hello();
  8. }
  9. }
  1. @Service
  2. public class UserService {
  3. public void hello() {
  4. System.out.println("UserService...");
  5. }
  6. }
  1. @SpringBootApplication
  2. public class ApplicationController {
  3. public static void main(String[] args) {
  4. ConfigurableApplicationContext context = SpringApplication.run(ApplicationController.class, args);
  5. UserController userController = (UserController) context.getBean("userController");
  6. userController.hello();
  7. }
  8. }

运行结果:

cc95d9f2778b43bf85133ded28ab198e.png


构造方法注入

构造方法注入就是在类的构造方法中注入依赖

  1. @Controller
  2. public class UserController {
  3. private UserService userService;
  4. public void hello() {
  5. System.out.println("UserController...");
  6. userService.hello();
  7. }
  8. @Autowired
  9. public UserController(UserService userService) {
  10. this.userService = userService;
  11. }
  12. }

注意:

① 如果类只有一个构造方法,那么 @Autowired 可以省略;如果有多个构造方法,那就需要加上这个注解指定要用哪个构造方法,如果没有指定,默认使用无参的构造方法

② 一般如果自己写了有参构造方法的话,建议把无参的构造方法也写出来


Setter 注入

这个也顾名思义,就是在 setter 方法上加 @Autowired

  1. @Controller
  2. public class UserController {
  3. private UserService userService;
  4. public void hello() {
  5. System.out.println("UserController...");
  6. userService.hello();
  7. }
  8. @Autowired
  9. public void setUserService(UserService userService) {
  10. this.userService = userService;
  11. }
  12. }
  1. @Service
  2. public class UserService {
  3. public void hello() {
  4. System.out.println("UserService...");
  5. }
  6. }
  1. @SpringBootApplication
  2. public class ApplicationController {
  3. public static void main(String[] args) {
  4. ConfigurableApplicationContext context = SpringApplication.run(ApplicationController.class, args);
  5. UserController userController = (UserController) context.getBean("userController");
  6. userController.hello();
  7. }
  8. }

运行结果:

b5e7f35834454368a44ea82abf5b80a5.png


三种注入的优缺点分析

  • 属性注入

优点:简洁方便(大部分情况下都用这种注入方式)

缺点:

① 只能用于 IoC 容器

② 不能注入被 final 修饰的属性

  • 构造方法注入

优点:

① 可以注入被 final 修饰的属性

② 注入的对象不会被修改

③ 依赖对象在使用前一定会被完全初始化,因为依赖是在类的构造方法中注入的,而构造方法在类加载阶段就会执行

④ 通用性好。因为构造方法是 JDK 支持的, 所以更换任何框架,它都是适用的。也就是说,不加 @Autowired 也可以顺利注入

缺点:注入多个对象时, 构造方法的代码会比较复杂

  • setter 注入

优点:在类实例化之后, 重新对该对象进行配置或注入比较方便

缺点:

① 也是不能注入被 final 修饰的属性

② 由于 setter 方法可能会被多次调用,所以注入对象有被修改的风险

对于这两种没法注入被 final 修饰的属性,有两种解决方式:

① 在构造方法中赋值

② 在定义时就进行初始化


@Primary、@Qualifier、@Resource

当同一个类存在多个 bean 时, 使用 @Autowired 就会有问题

  1. public class BeanConfig {
  2. @Bean
  3. public User user1() {
  4. User user = new User();
  5. user.setAge(24);
  6. user.setName("zhangsan");
  7. return user;
  8. }
  9. @Bean
  10. public User user2() {
  11. User user = new User();
  12. user.setAge(20);
  13. user.setName("lisi");
  14. return user;
  15. }
  16. }
  1. @Controller
  2. public class UserController {
  3. @Autowired
  4. private User user;
  5. @Autowired
  6. private UserService userService;
  7. @Autowired
  8. public void setUserService(UserService userService) {
  9. this.userService = userService;
  10. }
  11. public void hello() {
  12. System.out.println("UserController...");
  13. userService.hello();
  14. System.out.println(user);
  15. }
  16. }
  17. public class UserService {
  18. public void hello() {
  19. System.out.println("UserService...");
  20. }
  21. }

运行报错:有多个 Bean,不知道要把哪个注入到 UserController 的 User 对象

ac73aa03142049e8af9044f2f159c05d.png

可以用小标题那三个关键字来解决上述问题

使用
@Primary 注解,可以指定 Bean 默认的实现

  1. @Primary //指定该 bean 为默认 bean 的实现
  2. @Bean
  3. public User user1() {
  4. User user = new User();
  5. user.setAge(24);
  6. user.setName("zhangsan");
  7. return user;
  8. }

5877341bbd4f4b6d88ce21ef89f03f3d.png


使用
@Qualifier 注解可以指定当前要注入的 bean 对象:在
@Qualifier
value 属性中,指定注入的 bean 的名称

注意:
@Qualifier 注解必须配合
@Autowired 使用,不能单独用,

标签: java-ee spring java

本文转载自: https://blog.csdn.net/Ice_Sugar_7/article/details/140807103
版权归原作者 Script_7 所有, 如有侵权,请联系我们删除。

“「JavaEE」Spring IoC:依赖注入”的评论:

还没有评论