初识 Spring (存储和获取 bean)

目录

  • 初识 Spring
    • 总结
  • DI(依赖注入)
  • Spring 项目的创建
    • 创建一个 Maven 项目
    • 添加 Spring 框架支持
    • 添加启动类
  • 存储 bean 对象
    • 创建 bean
    • 将 bean 注册到容器中
  • 获取并使用 bean 对象
    • 获取 bean 的方法一
    • 获取 bean 的方法二
    • 获取 bean 的方法三
  • ApplicationContext 和 BeanFactory 的区别 (重点)
  • 总结

初识 Spring

Spring 是包含众多工具方法的 IoC 容器.

容器就是存储用的, 比如像以前学的 List / Map 就是存储数据的容器, 再像 Tomcat 就是 Web 容器.
容器最核心就是两点 : 存储和获取.

那 IoC 容器又是啥意思呢 ?
IoC = Inversion of Control 就是 “控制(权)反转” 的意思.

理解 :
以往我们获取对象都是通过 new 关键字来创建对象并获取的, 这样通过自己写代码控制类对象的生命周期, 我们是掌握对象控制权的, 而控制权反转就是指控制权不交由程序员控制了, 而是由 Spring(Spring容器 / IoC容器) 来控制.

IoC 容器就是存放 bean(对象) 的容器, 我们如果需要就去容器获取, 不需要自己 new 对象了.

这样有什么好处呢 ?
对代码进行解耦, 即使底层类发生改变, 整个调用链都不需要改动, 使程序设计更加通用, 灵活.

举个例字 :
我有两个类 :

public class B {
    private int b = 25;
    public B() {
        System.out.println("b : " + b);
    }
}
public class A {
    public A() {
        B b = new B();  // A 类依赖 B 类
    }
}

测试类 :

public class Test {
    public static void main(String[] args) {
        A a = new A();  //传统是直接 new 对象
    }
}

如果我要对 B 类的 b 进行修改, 那只能修改底层的 B 类代码 :

public class B {
    private int b = 25;
    public B(int m) {
        b = m;
        System.out.println("b : " + b);
    }
}

B 的构造方法变了, A 类的构造方法也要变 :

public class A {
    public A(int m) {
        B b = new B(m);
    }
}

测试类 :

public class Test {
    public static void main(String[] args) {
        A a = new A(66);
    }
}

我们只是改动底层代码一点点, 就牵一发而动全身了, 这显然很麻烦, 它们的耦合太强了, IoC 容器就解决了这一点, 让程序员修改底层代码而不动整个调用链.

总结

Spring 是⼀个 IoC 容器,对象的创建和销毁都交给 Spring 来管理了,它本身⼜具备了存储对象和获取对象的能⼒。

DI(依赖注入)

DI 是 Dependency Injection 的缩写, 翻译成中⽂是“依赖注⼊”的意思.
所谓依赖注⼊, 就是由 IoC 容器在运⾏期间, 动态地将某种依赖关系注⼊到对象之中.

DI 与 IoC 区别:
DI 和 IoC 是从不同角度描述同一件事情,IoC 是一种思想,它就是要实现对像解耦,不管用什么样的方法;DI 则是一种具体手段,来实现对象解耦.

Spring 项目的创建

创建一个 Maven 项目

初识 Spring (存储和获取 bean)_第1张图片
初识 Spring (存储和获取 bean)_第2张图片

添加 Spring 框架支持

在项⽬的 pom.xml 中添加 Spring 框架的⽀持,xml 配置如下 :

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.2.3.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-beans</artifactId>
		<version>5.2.3.RELEASE</version>
	</dependency>
</dependencies>

添加的框架有 spring-context:spring 上下⽂,还有 spring-beans:管理对象的模块。

注意 : 这里只是声明要这些依赖, 以及依赖所在地, 并不是添加完上述代码就添加完了依赖, 还得刷新一下, 让 idea 去下载这些依赖.

添加启动类

最后在创建好的项⽬ java ⽂件夹下创建⼀个启动类,包含 main ⽅法即可:

public class App {
    public static void main(String[] args) {
        
    }
}

存储 bean 对象

想存储 bean 对象, 首先得有 bean 才行, 因此首先得创建一个 bean, 然后将 bean 注册到 Spring 容器中.

创建 bean

bean 就是 Java 中 一个普通对象, 创建 bean 就是创建对象.

初识 Spring (存储和获取 bean)_第3张图片

将 bean 注册到容器中

在创建好的项⽬中添加 Spring 配置⽂件 spring-config.xml,将此⽂件放到 resources 的根⽬录下,
如下图所示:
初识 Spring (存储和获取 bean)_第4张图片
在 spring-config.xml 中添加 Spring 配置⽂件 :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
</beans>

再将 Student 对象注册到 Spring 中就可以,具体操作如下:
初识 Spring (存储和获取 bean)_第5张图片

注意 :
class 是对应你要注册的类的路径, 当我们获取 bean 的时候就会去这个路径中扫描, 如果扫描不到就会报错;
id 这里是可以随便取的, 只是给这个路径中注册的 bean 对象取个名字, 方便后续获取.
如果存在多个 bean 需注册, 则添加多个 < bean > 标签

获取并使用 bean 对象

获取并使⽤ Bean 对象,分为以下 3 步:

  1. 得到 Spring 上下⽂对象,因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那
    么就得先得到 Spring 的上下⽂。
  2. 通过 Spring 上下⽂,获取某⼀个指定的 Bean 对象。
  3. 使⽤ Bean 对象。

获取 bean 的方法一

public class App {
    public static void main(String[] args) {
        //1. 获取 spring 上下文对象, 注意后面需填写添加配置的文件名称
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //2. 获取 bean 对象, 后面的字符串要与我们之前取的名字相匹配, 
        //   获取到的 bean 是 object 类型的, 需强制类型转换
        Student student = (Student)context.getBean("student");
        //检验对象是否获取到
        System.out.println(student.sayHi("佩奇"));
    }
}

初识 Spring (存储和获取 bean)_第6张图片

获取 bean 的方法二

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //这里是直接通过类类型来获取 bean 对象, 所以返回的值不需要转换
        Student student = context.getBean(Student.class);
        //Student student = (Student)context.getBean("student");
        System.out.println(student.sayHi("佩奇"));
    }
}

当我们 Student 仅有一个 bean 对象时, 这样直接通过类名来获取 bean 对象显然没问题, 但若 Student 存在多个 bean 对象呢 ? 它会获取到哪个 bean 对象呢 ?
初识 Spring (存储和获取 bean)_第7张图片
这里我们载注册一个 Student 类的 bean 对象, 并取名为 student2.
来看看获取效果 :
初识 Spring (存储和获取 bean)_第8张图片
报错信息是 : 找到两个匹配结果, 但它只期望有一个结果.
如果是用 id 来获取就不会出现这种情况了, 因为每个 bean 都有唯一的 id.

获取 bean 的方法三

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //通过 id 获取 bean, 并将所得 bean 转为 Student 类型, 无需类型转换了
        Student student = context.getBean("student", Student.class);
        //Student student = context.getBean(Student.class);
        //Student student = (Student)context.getBean("student");
        System.out.println(student.sayHi("佩奇"));
    }
}

ApplicationContext 和 BeanFactory 的区别 (重点)

其实 BeanFactory 也可以获取 Bean 对象.

public class App {
    public static void main(String[] args) {
        BeanFactory context = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
        //ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //通过 id 获取 bean, 并将所得 bean 转为 Student 类型, 无需类型转换了
        Student student = context.getBean("student", Student.class);
        //Student student = context.getBean(Student.class);
        //Student student = (Student)context.getBean("student");
        System.out.println(student.sayHi("佩奇"));
    }
}

ApplicationContext 和 BeanFactory 效果是⼀样的, 那它们之间的区别是什么呢 ?

区别 :

  1. ApplicationContext 是 BeanFactory 的子类, ApplicationContext 不仅拥有父类的所有方法, 还扩展了很多父类没有的方法. (国际化支持、资源访问支持、事件传播支持等)
  2. ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象, ⽽ BeanFactory 是懒加载(需要哪个才去加载哪个), 因此更加轻量.

总结

  1. 操作容器之前, 先要有容器, 所以先要得到容器.
  2. 存对象
    a. 创建 Bean (普通类).
    b. 将 Bean 注册(配置)到 spring-confing.xml 中.
  3. 取对象
    a. 得到 Spring 上下⽂, 并读取到 Spring 的配置⽂件.
    b. 获取某⼀个 Bean 对象.
    c. 使⽤ Bean 对象.

你可能感兴趣的:(JavaEE,spring,java)