IOC的提出

在传统的javaweb中,程序员自己定义的pojo对象之后还得要自己进行创建有许多的类都耦合到一起去了。假如咱编写bean的时候脑子不清晰,写错了逻辑又没反应过来后面继续使用这个bean就会引起连锁反应,大家一起完蛋。所以在Spring中便提出了IOC(控制反转)原来创建bean实例的活都交给了Spring容器去做,我们在需要使用的时候只需从容器中取出即可,非常的人性化。

注入之前的准备

  1. 创建bean文件夹

首先在com.cdd的目录下创建一个pojo文件夹

image-20230228223028171

之后的bean都是创建在这个pojo文件夹里的(虽然之前web学过)

然后创建一个bean对象如下

public class Message1 {
    String msg;
    public Message1(String msg) {
        this.msg = msg;
    }
        public void setMsg(String msg) {
        this.msg = msg;
    }
    public void show() {
        System.out.println(this.msg + "欢迎来到Spring");
    }
}
  1. 创建相关的xml文件

然后就需要在resource下创建一个xml文件来创建bean拉,首先需要写出以下内容

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--这里写bean标签-->
    <bean id="msg" class="com.cdd.pojo.Message1">
    	<constructor-arg name="msg" value="123"></constructor-arg>
        <property name="msg" value="hello"></property>
    </bean>
</beans>

现在已经给标签标

  1. 使用容器

这里咱可以使用applicationContext接口或者是beanFactory接口来创建一个工厂并用他们来构建bean对象,这边先使用applicationContext吧。代码如下

//  加载相关的配置
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//  获取相关信息
Object msg = applicationContext.getBean("msg");
//  输出相关信息
System.out.println(msg);

最后系统会打印出这样一段虚拟化之后的地址

image-20230228225158565

这样就成功通过一个Spring容器来构建了一个bean实例对象,不用再让我们new一个了。但是或许哪里注入了呢?其实在编写xml的bean标签时便已经把信息狠狠的注入到对象里面了。还有一种beanFactory其实就是applicationContext的实现底层,它只是把beanFactory稍微进行了封装,并且相比于beanFactory还多出了些许的功能。接下来在使用beanFactory打印msg。

 // 创建beanFactory
 DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
 // 创建读取器
 XmlBeanDefinitionReader reader =  new XmlBeanDefinitionReader(factory);
 //  加载配置文件
 reader.loadBeanDefinitions("applicationContext.xml");
 //  获取对象并输出
 Object msg1 = factory.getBean("msg");
System.out.println(msg1);

最终也打印出如上地址

image-20230228230520982

beanFactory和ApplicationContext的关系

  1. beanFactory是Spring的早期接口成为bean工厂,另一个是之后实现的更高级的接口称之为Spring容器
  2. applicationContext在底层还是维持对beanFactory的引用,并且除此之外还有监听等功能
  3. applicationContext不仅维持对beanFactory的继承,还和它存在这融合关系
  4. Bean的初始化时机不同,beanFactory在要调用的时候才创建bean,而applicationContext在刚刚开始就已经初始化完毕了

bean对象在底层是如何进行创建的

我们配置下xml文件中的信息再get一下bean就得到了一个bean对象,但是这中间Spring容器时如何进行创建的?

在Spring中存在一个BeanDefinition 类,它是把咱们的xml配置文件中的bean标签里的信息封装成为一个对象,不是把bean标签里的bean封装为对象,而是封装bean标签里我们设置的那些信息(如: scope之类的),然后把这些封装完毕的对象存储到beanDefinitionMap的Map集合中,源码如下:

    private final Map<String, BeanDefinition> beanDefinitionMap;

String便是name,接着再通过java的反射技术把这些对象实例化成我们想要的Bean实例对象,最终通过getBean返回我们想要的实例对象。