【JavaEE进阶】 依赖注?DI详解

发布时间:2024年01月19日

🌴什么是依赖注入

依赖注?是?个过程,是指IoC容器在创建Bean时,去提供运?时所依赖的资源,?资源指的就是对象.

简单来说,就是把对象取出来放到某个类的属性中.

在?些?章中,依赖注?也被称之为"对象注?",“属性装配”,具体含义需要结合?章的上下?来理解

🎄依赖注入的三种方法

关于依赖注?,Spring也给我们提供了三种?式:

  1. 属性注?(Field Injection)

  2. 构造?法注?(Constructor Injection)

  3. Setter注?(Setter Injection)

🚩属性注?(Field Injection)

属性注?是使? @Autowired 实现的。

比如我们将StudentService类注?到StudentController类中.

StudentService.java代码如下:

@Service
public class StudentService {
    public void run() {
        System.out.println("StudentService启动");
    }
}

StudentController.java代码如下:

@RestController
public class StudentController {
    @Autowired
    private StudentService studentService;
    public void run() {
    	System.out.println("StudentController启动");
        studentService.run();
    }
}

获取StudentController中的run方法

@SpringBootApplication
public class SpringMvcApplication {

    public static void main(String[] args) {
        //获取spring上下文
        ApplicationContext context = SpringApplication.run(SpringMvcApplication.class, args);
        //从spring中获取对象
        StudentController studentController = context.getBean("studentController",StudentController.class);
        //使用spring对象
        studentController.run();
    }

}

启动项目,结果如下:

在这里插入图片描述

🚩构造?法注?

构造?法注?是在类的构造?法中实现注?,如下代码所?:

@RestController
public class StudentController {

    private StudentService studentService;

    public StudentController() {
    }
    
    @Autowired
    public StudentController(StudentService studentService) {
        this.studentService = studentService;
    }
    public void run() {
        System.out.println("StudentController启动");
        studentService.run();
    }

}

结果展示:

在这里插入图片描述
注意事项:

  • 如果类只有?个构造?法,那么@Autowired注解可以省略;如果类中有多个构造?法,那么需要添加上@Autowired来明确指定到底使?哪个构造?法
  • 如果存在多个构造方法,还没有写注解的话,就会出现以下问题
    在这里插入图片描述

🚩Setter注?

Setter注?和属性的Setter?法实现类似,只不过在设置set?法的时候需要加上@Autowired注解

@RestController
public class StudentController {

    private StudentService studentService;

    @Autowired
    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }
    public void run() {
        System.out.println("StudentController启动");
        studentService.run();
    }

}

在这里插入图片描述

🚩三种注?的优缺点

属性注?:

  • 优点:

    • 简洁,使??便;
  • 缺点:

    • 只能?于IoC容器,如果是?IoC容器不可?,并且只有在使?的时候才会出现NPE(空指针异常)

    • 不能注??个Final修饰的属性

构造函数注?(Spring 4.X推荐):

  • 优点:
    • 可以注?final修饰的属性

    • 注?的对象不会被修改

    • 依赖对象在使?前?定会被完全初始化,因为依赖是在类的构造?法中执?的,?构造?法是在类加载阶段就会执?的?法.

    • 通?性好,构造?法是JDK?持的,所以更换任何框架,他都是适?的

  • 缺点:
    • 注?多个对象时,代码会?较繁琐

Setter注?(Spring3.X推荐):

  • 优点:

    • ?便在类实例之后,重新对该对象进?配置或者注?
  • 缺点:

    • 不能注??个Final修饰的属性

    • 注?对象可能会被改变,因为setter?法可能会被多次调?,就有被修改的?险.

🌳@Autowired存在的问题

当同?类型存在多个bean时,在使?@Autowired就会存在问题

比如我们有以下bean。

BeanFiguation.java代码如下:

@Configuration
public class BeanFiguation {
    @Bean
    public Student student1() {
        Student student = new Student();
        student.setId(11);
        student.setName("遇事");
        student.setAge(11);
        return student;
    }
    @Bean
    public Student student2() {
        Student student = new Student();
        student.setId(22);
        student.setName("问春风乄");
        student.setAge(22);
        return student;
    }
}

StudentController.java代码如下:

@RestController
public class StudentController {

    @Autowired
    private Student student;

    public void run() {
        System.out.println(student);
    }
}

当我们进行启动时:
在这里插入图片描述
报错的原因是,?唯?的 Bean 对象

在这里插入图片描述

🌲解决@Autowired存在的问题

为了解决上述问题,Spring提供了以下4种解决?案:

  • bean对象名称与属性名相匹配
  • @Primary
  • @Qualifier
  • @Resource

第一种:bean对象名称与属性名相匹配

在这里插入图片描述

第二种:使?@Primary注解:当存在多个相同类型的Bean注?时,加上@Primary注解,来确定默认的实现.

在这里插入图片描述

第三种:使?@Qualifier注解:指定当前要注?的bean对象。在@Qualifier的value属性中,指定注?的bean的名称。

  • @Qualifier注解不能单独使?,必须配合@Autowired使?

在这里插入图片描述
在这里插入图片描述

第四种:使?@Resource注解:是按照bean的名称进?注?。通过name属性指定要注?的bean的名称。

在这里插入图片描述

在这里插入图片描述

🍃@Autowird与@Resource的区别

  • @Autowired是spring框架提供的注解,?@Resource是JDK提供的注解

  • @Autowired默认是按照类型注?,?@Resource是按照名称注?.相?于@Autowired来说,@Resource?持更多的参数设置,例如:name设置,根据名称获取Bean。

?总结

关于《【JavaEE进阶】 依赖注?DI详解》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

文章来源:https://blog.csdn.net/m0_71731682/article/details/135696783
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。