0


「JavaEE」Spring IoC:依赖注入

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

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

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

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

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


属性注入

使用 **

@Autowired

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

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    public void hello() {
        System.out.println("UserController...");
        userService.hello();
    }
}
@Service
public class UserService {
    public void hello() {
        System.out.println("UserService...");
    }
}
@SpringBootApplication
public class ApplicationController {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(ApplicationController.class, args);
        UserController userController = (UserController) context.getBean("userController");
        userController.hello();
    }
}

运行结果:

cc95d9f2778b43bf85133ded28ab198e.png


构造方法注入

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

@Controller
public class UserController {
    private UserService userService;

    public void hello() {
        System.out.println("UserController...");
        userService.hello();
    }

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

注意:

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

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


Setter 注入

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

@Controller
public class UserController {
    private UserService userService;

    public void hello() {
        System.out.println("UserController...");
        userService.hello();
    }

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}
@Service
public class UserService {
    public void hello() {
        System.out.println("UserService...");
    }
}
@SpringBootApplication
public class ApplicationController {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(ApplicationController.class, args);
        UserController userController = (UserController) context.getBean("userController");
        userController.hello();
    }
}

运行结果:

b5e7f35834454368a44ea82abf5b80a5.png


三种注入的优缺点分析

  • 属性注入

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

缺点:

① 只能用于 IoC 容器

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

  • 构造方法注入

优点:

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

② 注入的对象不会被修改

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

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

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

  • setter 注入

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

缺点:

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

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

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

① 在构造方法中赋值

② 在定义时就进行初始化


@Primary、@Qualifier、@Resource

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

public class BeanConfig {
    @Bean
    public User user1() {
        User user = new User();
        user.setAge(24);
        user.setName("zhangsan");
        return user;
    }

    @Bean
    public User user2() {
        User user = new User();
        user.setAge(20);
        user.setName("lisi");
        return user;
    }
}
@Controller
public class UserController {
    @Autowired
    private User user;
    @Autowired
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void hello() {
        System.out.println("UserController...");
        userService.hello();
        System.out.println(user);
    }
}

public class UserService {
    public void hello() {
        System.out.println("UserService...");
    }
}

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

ac73aa03142049e8af9044f2f159c05d.png

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

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

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

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:依赖注入”的评论:

还没有评论