【Spring】Ioc容器和Bean对象

一、Spring框架

我们通常所说的 Spring 指的是Spring Framework (Spring框架) ,它是一个开源框架,有着活跃而庞大的社区,这就是它之所以能⻓久不衰的原因,Spring支持广泛的应用场景,它可以让 Java 企业级的应用程序开发起来更简单。

1.1 Spring Ioc容器

什么是容器?容器就是能装下许多东西的空间结构,例如图书架,能随时找到自己想要的书,而Spring也是一个容器,它是一个IoC容器
什么是Ioc容器

IoC = Inversion of Control 翻译成中文是 “ 控制反转 ” 的意思 , 也就是说Spring 是一个“控制反转”的容器。

1.2 控制反转

传统应用开发,比如我们现在要构建一辆车的程序,我们的开发流程可能是这样的
在这里插入图片描述
构建一辆车,车依赖车身,车身依赖底盘,底盘依赖轮胎。
传统开发代码示例如下,伪代码示例

public class NewCarExample {
    public static void main ( String [ ] args) {
        Car car = new Car (30);
        car.init ();
    }
    /*
    汽车对象
     */
    private static class Car {
     private Body body;
        public Car(int size){
           body = new Body(size);
        }
        public void init ( ) {
           // 依赖⻋身
            body.init();
        }
    }
    /*
    车身对象
     */
    private static class Body{
        private Bassplate bassplate;
        public Body(int size){
              bassplate = new Bassplate(size);
        }
        public void init(){
            //依赖底盘
            bassplate.init();
        }
    }
    /*
    车身底盘
     */
    private static class Bassplate{
        private Tire tire;
        public Bassplate(int size){
              tire = new Tire(size);
        }
        public void init(){
            //依赖轮胎
            Tire tire = new Tire();
         
        }
    }
    /*
    轮胎
     */
    private static class Tire {
        private int size ;
        public Tire(int size) { 
            this.size = size;
        }
        public void init(){
            System . out . println ( " 轮胎尺寸 : " + size);
        }
    }
}


在以上程序中,轮胎的尺寸是固定的,在开发需求量越来越大的时候,假如我们需要对轮胎尺寸进行修改,就需要对上述底层代码进行修改,上述底层代码修改之后,其他类的代码块也得面临修改的问题。一不小心就容易出错。
根据以上示例,我们改造一下上述代码,采用注入传递的方式

public class IocCarExample {
    public static void main ( String [ ] args) {
        Tire tire = new Tire ( 20);
        Bassplate bassplate = new Bassplate ( tire);
        Body body = new Body ( bassplate);
        Car car = new Car (body);
        car.run ();
    }
    static class Car {
        private Body body ;
        public Car ( Body body ) {
            this.body= body;
        }
        public void run() {
            body.init();
        }
    }
    static class Body {
        private Bassplate bassplate ;
        public Body ( Bassplate bassplate) {
            this.bassplate = bassplate;
        }
        public void init ( ) {
            bassplate.init ();
        }
    }
    static class Bassplate {
        private Tire tire ;
        public Bassplate ( Tire tire ) {
            this.tire = tire;
        }
        public void init () {
            tire.init();
        }
    }
    static class Tire {
        private int size ;
        public Tire ( int size ) {
            this.size = size;
        }
        public void init (){
            System.out.println( " 轮胎 : " + size);
        }
    }
}

再来看实现逻辑
在这里插入图片描述
代码这样调整,无论底层类如何变化,其他类的代码不需要进行修改
我们发现了一个规律: 通用程序的实现代码 , 类的创建顺序是反的 , 传统代码是 Car 控制并创建了
Body, Body控制并创建了 Ballplate , 依次往下 , 而改进之后的控制权发生的反转,不再是上级对象创建并控制下级对象了 , 而是下级对象把注入将当前对象中 , 下级的控制权不再由上级类控制了 , 这样即使下级类发生任何改变 , 当前类都是不受影响的 , 这就是典型的控制反转 , 也就是 IoC 的实现思想 。

1.3 理解IoC

Spring 是包含众多工具方法的容器,我们如何理解容器这两个字,容器具备最基础的两个功能

  • 把对象存入容器
  • 从容器中取出对象

也就是说,spring最核心的功能,就是学习如何将对象存入容器中,再从spring中取出对象的方法。

将对象存放到容器中的好处: 将对象存储在 IoC 容器相当于将以后可能用的所有工具制作好都放到仓库中, 需要的时候直接取就行了, 用完再把它放回到仓库。 而 new 对象的方式相当于,每次需要工具了才实现,用完就扔掉了也不会保存,下次再用的时候还得重新实现, 这就是IoC 容器和普通程序开发的区别。

通过以上理解,我们可以认为我们就是把对象的创建和销毁的权利都交给 Spring 来管理了,它本身又具备了存储对象和获取对象的能力

1.4 DI

说到 IoC 就得提到一个词就是 “ DI ” , DI 是 Dependency Injection 的缩写,翻译成中文是“依赖注入 ”的意思。所谓依赖注入 , 就是由IoC容器在运行期间 , 动态地将某种依赖关系注入到对象之中。所以,依赖注入 ( DI ) 和控制反转 (IoC) 是从不同的角度的描述的同一件事情 , 就是指通过引入 IoC容器 , 利用依赖关系注入的方式 , 实现对象之间的解耦。

也就说依赖注入是一种消除类之间依赖关系的设计模式。 例如,A类要依赖B类,A类不再直接创建B类,而是把这种依赖关系配置在外部xml文件(或java.config文件)中,然后由Spring容器根据配置信息创建、管理bean。

那么什么是Bean?Bean类如何注入Spring容器?

二 、Bean对象

2.1 什么是Bean?

  • Bean被实例化的,是被Spring框架所管理的Java对象。
  • Spring容器会自动完成Bean的实例化。将所创建的的Bean自动注入到Ioc容器中以供调用。
  • 创建应用对象之间的协作关系的行为被称为:装配,这就是依赖注入的本质

2.2 maven的创建

1.首先在编译器中创建Maven项目,因为Spring是基于maven的。

在这里插入图片描述2.项目依赖引入国内镜像源地址配置
由于maven默认引入依赖的地址是国外的地址,在引入依赖的时候可能会引入失失败,所以这里采用国内的镜像源地址
在这里插入图片描述已经配置好的settings.xml文件:settings.xml
3.项目中添加依赖
在这里插入图片描述

在maven项目中添加对Spring的支持,粘贴之后刷新maven项目即可。

<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>

2.3 bean的创建和使用

1.创建启动类测试
在这里插入图片描述
2.设置bean对象存储文件
文件以.xml结尾,文件名称取什么都可以,例如我这里叫javaconfig
在这里插入图片描述配置文件如下:

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

3.创建一个bean对象

package org.example.demo;

public class Car {
    public void init(String name){
        System.out.println("我是一辆车,我的品牌是"+name);
    }
}

4.通过已经创建好的配置文件,注入Spring容器当中,注入格式如下

<bean id="car" class="org.example.demo.Car"></bean>

在这里插入图片描述
5.注入bean到spring容器中如何取出使用

  • 想要从 Spring 中将Bean对象读取出来,先要得到 Spring 上下文对象,相当于得到了 Spring 容器。

  • 再通过 spring 上下文对象提供的方法获取到需要使用的Bean对象,最后就能使用Bean对象了。

  • 使用ApplicationContext就可以将容器中的对象取出来。

需要使用到的配置文件读取类

ClassPathXmlApplicationContext(常用)	加载类路径下的配置文件,要求配置文件必须在类路径下

6.通过上下文对象来取出bean对象并使用其中的方法

public class Test {
    public static void main(String[] args) {
        //得到上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("javaconfig.xml");
        //根据id获取已经存入的bean对象
        Car car = (Car) context.getBean("car");
        //使用已经存入的bean
        car.init("比亚迪");
    }
}

运行结果如下:
在这里插入图片描述
7.通过bean工厂来取出其中的bean对象并使用

public class Test2 {
    public static void main(String[] args) {
        // 1. 得到 bean 工厂
        BeanFactory factory = new XmlBeanFactory(new ClassPathResource("javaconfig.xml"));
        // 2. 获取 bean 对象 也是通过id获取
        Car student = (Car) factory.getBean("car");
        // 3. 使用 bean
        student.init("哈哈哈哈");
    }
}

运行结果如下
在这里插入图片描述
我们发现两种方式都可以取出bean对象,那么他们又有什么不同呢?

2.4 ApplicationContext VS BeanFactory

1.对比

  • 继承关系和功能方面来说: Spring 容器有两个顶级的接口: BeanFactory 和 ApplicationContext。 其中 BeanFactory 提供了基础的访问容器的能力, 而 ApplicationContext 属于 BeanFactory 的子类, 它除了继承了 BeanFactory 的所有功能之外, 它还拥有独特的特性, 还添加了对国际化支持、 资源访问支持、以及事件传播等方面的支持。
  • 性能方面来说: ApplicationContext 是一次性加载并初始化所有的 Bean 对象, 而 BeanFactory 是需要那个才去加载那个, 因此更加轻量。

简单来说,ApplicationContext是饿汉模式,一次性加载通过配置文件注入到容器的所有bean对象。BeanFactory 是懒汉模式,当你要使用某个bean的时候,他才会加载注入到容器的bean对象
结论验证:
我们再创建一个bean对象,并在已经创建后的bean对象里面加入构造方法

public class Car {
    public Car(){
        System.out.println("Car加载");
    }
    public void init(String name){
        System.out.println("我是一辆车,我的品牌是"+name);
    }
}

public class Person {
    public Person() {
        System.out.println("Person加载");
    }

    public void speak(){
        System.out.println("我是一个人");
    }
}

分别调用

public class Test3 {
    public static void main(String[] args) {
        //得到上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("javaconfig.xml");
        System.out.println("=======================================================================");
        //bean工厂
        BeanFactory factory = new XmlBeanFactory(new ClassPathResource("javaconfig.xml"));
    }
}

结果:
结论验证成功。
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值