深入IoC(1)

Created
Oct 30, 2021 05:27 AM
Tags
Spring
在上一篇文章中我们创建了第一个Spring程序,通过ApplicationContext 加载了我们的bean.xml 文件,并且通过getBean 获取了我们的User 类的实体对象,那么我们并没有用new 关键词创建对象,究竟是怎么得到User对象的?
这里就用到了Spring的核心概念IoC

什么是IoC?

官方文档是这样解释的
This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) [1]principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.
Spring是通过底层的一个工厂来加载我们自己编写的Java类,当我们有需要用到这个类的实例对象的时候,找Spring去拿就行了。

为什么要用IoC?

在传统Java项目开发中,如果我在另一个类中需要加载其他类的时候,必须通过new 关键词去获取实例对象,再调用相关的方法,这样就会出现几个问题。
  1. 项目的耦合度太高,如果我需要的另一个类重写了,例如类名等变了,那么我就需要去改当前类,极大的增加了开发难度,后期的大项目变成臃肿,难以维护。
  1. 如果又有新的类需要用到另一个类了,反复的new 会导致内存的浪费,降低虚拟机的性能。

怎么用IoC?

Spring底层通过BeanFactory 工厂来管理所有的类
@Test
public void test01(){
		ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
		User user = context.getBean("user", User.class);
		System.out.println(user);
		user.print();
}
代码回顾
ApplicationContextBeanFactory 的一个实现,Spring主要通过这两个接口来加载我们的类,上述代码中可以直接替换为BeanFactory 也能实现bean 的加载,那我们为什么要用ApplicationContext
两者的区别 BeanFactory 是供Spring内部使用的类,一般我们开发人员不会直接去使用他。在加载bean 的时候,不会直接创建对象,而是等到要使用对象的时候才会去加载
ApplicationContextBeanFactory 的子类,功能更加强大,是开发中使用的类。在加载bean 的时候,会直接创建对象。
我们只需要编写我们的配置文件bean.xml ,再通过ApplicationContext 就可以使用了。

通过注解使用beanFactory

@Test
public void test02(){
		ApplicationContext context = new AnnotationConfigApplicationContext("demo");
		User user = context.getBean("user", User.class);
		System.out.println(user);
		user.print();
}
我们还可以用AnnotationConfigApplicationContext 这个类去加载我们的bean,需要告诉Spring要扫描哪个包下的类的,同时要在需要加载的类加上@Component注解
package demo.entity;

import org.springframework.stereotype.Component;

@Component
public class User {
    
    public void print(){
        System.out.println("我是user类");
    }
}