Spring(一)

时间:2022-10-05 16:53:45

Spring(一)

 咱Spring

目录

1.什么是Spring

2.如何理解Spring

3.IoC和DI

           3.1loc

           3.2DI

           3.3两者有什么区别?

4.Spring最核心的功能是啥?

5.Spring的创建与使用

           5.1创建一个Maven项目

           5.2添加Spring类xml

           5.3测试启动类

6.存入Bean

           6.1添加配置文件(非第一步省略此步骤)

           6.2创建Bean对象

                        6.2.1创建Bean对象

                        6.2.2将Bean对象注入到Spring

          6.3获取并使用Bean对象

                       6.3.1先得到Spring上下文对象

                       6.3.2再通过上下文提供的方法获取到Bean对象

                       6.3.3使用Bean对象


1.什么是Spring

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

2.如何理解Spring

Spring 是包含了众多⼯具⽅法的 IoC 容器。

对象存放在容器中的好处:

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

3.IoC和DI

           3.1loc

①什么是容器?

顾名思义就是储存东西的容器,在此之前,我们也学过不少容器,比如,存储数据的map/list;以及web的容器Tomcat等。

②什么是loC容器?

IoC(Inversion of Control) 其实就是“控制反转”的意思。那么这里的“控制反转”究竟是什么意思呢?让我们看看下面这个示例:
假设我们现在构建一辆“车”的程序
(1)传统程序开发:
a.构造本车的逻辑图为:
Spring(一)

 我们由图可以发现,要想构造一个车,就需要先构造车身,而车身就需要先构造底盘,同样,底盘需要先构造轮胎。然后就成了这样的依赖关系。那么这个时候,我们可以写出下列代码:

public class NewCarProduce {
    public static void main(String[] args) {
        Car car = new Car();
        car.init();
    }
    /**
     * 汽⻋对象
     */
    static class Car {
        public void init() {
            // 依赖⻋身
            Framework framework = new Framework();
            framework.init();
        }
    }
    /**
     * ⻋身类
     */
    static class Framework {
        public void init() {
            // 依赖底盘
            Bottom bottom = new Bottom();
            bottom.init();
        }
    }
    /**
     * 底盘类
     */
    static class Bottom {
        public void init() {
            // 依赖轮胎
            Tire tire = new Tire();
            tire.init();
        }
    }
    /**
     * 轮胎类
     */
    static class Tire {
        // 尺⼨
        private String color= "yellow";
        public void init() {
            System.out.println("轮胎的颜色:" + color);
        }
    }
}

输出结果:

Spring(一)

我们可以发现,这就是我们刚刚说的通过依赖关系进行层层调用的例子,但是我们很快可以发现一个缺点,要是这个时候,用户提了新的需求,那么我们就需要对整个代码全部修改,比如,这个时候,用户要去定制轮胎的颜色,这个时候操作的流程如下。

Spring(一)

 此时代码:

import java.util.Scanner;

public class NewCarProduce {
    public static void main(String[] args) {
        System.out.println("请输入你想要的轮胎颜色:");
        Scanner sc=new Scanner(System.in);
        String color=sc.nextLine();
        Car car = new Car();
        car.init(color);
    }
    /**
     * 汽⻋对象
     */
    static class Car {
        public void init(String color) {
            // 依赖⻋身
            Framework framework = new Framework();
            framework.init(color);
        }
    }
    /**
     * ⻋身类
     */
    static class Framework {
        public void init(String color) {
            // 依赖底盘
            Bottom bottom = new Bottom();
            bottom.init(color);
        }
    }
    /**
     * 底盘类
     */
    static class Bottom {
        public void init(String color) {
            // 依赖轮胎
            Tire tire = new Tire();
            tire.init(color);
        }
    }
    /**
     * 轮胎类
     */
    static class Tire {
        // 尺⼨
//        private String color= "yellow";
        public void init(String color) {
            System.out.println("轮胎的颜色:" + color);
        }
    }
}

 这个时候我们论证了开始我们的想法,而且在实际的开发中,这个链只会更长,要是每当用户提出了新的要求,我们就进行改动,那这个工作效率是极低的,开销是很大的。

b.问题:

当最底层代码改动之后,整个调⽤链上的所有代码都需要修改。

c.解决方式:

解耦(当我们修改下面底层的东西时,上面的代码可以不用更改);

(2)控制反转式程序开发:(用到了Ioc原理)

造成前面所发生问题的原因就是我们把依赖控制生命权掌握到了自己手上,这个时候依赖类发生改变代码就会进行响应调整。这个时候我们应该怎么做呢?我们需要把控制权反转,不管它的生命周期,当我们要使用的时候,就告诉loC容器,让容器把这个类给我,然后直接去用。下面主要展示其实现。

a.构造本车的逻辑图:

Spring(一)

这个时候,当我们无论需要增添修改什么,都只需要在第一行代码的参数上加对应的属性,然后在Tire类里进行修改:

Spring(一) 此时修改成双属性后,代码如下:

import java.util.Scanner;
public class NewCarProduce {
    public static void main(String[] args) {
        Tire tire=new Tire("pink",60);
        Bottom bottom=new Bottom(tire);
        Framework framework=new Framework(bottom);
        Car car = new Car(framework);
        car.run();
    }
    /**
     * 汽⻋对象
     */
    static class Car {
        private Framework frameWork;
        public Car(Framework frameWork) {
           this.frameWork=frameWork;
        }
        public void run(){
            frameWork.init();
        }
    }
    /**
     * ⻋身类
     */
    static class Framework {
        private Bottom bottom;
        public Framework(Bottom bottom) {
            this.bottom=bottom;
        }
        public void  init(){
            bottom.init();
        }
    }
    /**
     * 底盘类
     */
    static class Bottom {
        private Tire tire;
        public Bottom(Tire tire) {
           this.tire=tire;
        }
        public void init(){
            tire.init();
        }
    }
    /**
     * 轮胎类
     */
    static class Tire {
        public  int size;
        String color;
        public Tire(String color,int size){
            this.color=color;
            this.size=size;
        }
        public void init() {
            System.out.println("轮胎的颜色:" + color+"轮胎的尺寸为:"+size);
        }
    }
}

 成功地实现了解耦。改进之后的控制权发的反转,不再是上级对象创建并控制下级对象了,是下级对象把注将当前对象中,下级的控制权不再由上级类控制 了,这样即使下级类发任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现想。

通过以上讲解,想必大家对“控制反转”都有了自己新的理解了。

③loC的优点:

(1)实现代码的解耦

(2)对象(java中每个对象可以称其为Bean)的生命周期交给loC框架来维护,程序员本身无需再对其进行关注。

④loC的核心功能:

(1)把对象存储到Spring中,
(2)把对象从Spring中取出来。

           3.2DI

DI 是 Dependency Injection的缩写,翻译成中是“依赖注”的意思。

           3.3两者有什么区别?

简单来说,loC 是一种思想,而DI是一种实现。

举个例子:

高三的孩子们都有自己的想法,都准备努力考上理想的大学,那么这个时候,考上理想的大学就是思想和目标就是loC,而最后考上的究竟是一本,211,985?这就是具体的实现,就是DI。

4.Spring最核心的功能是啥?

(1)把对象存储到Spring中。
(2)把对象从Spring中取出来。

5.Spring的创建与使用

           5.1创建一个Maven项目

就和我们前面讲的创建Maven是一模一样的,这里就不再复述了。

           5.2添加Spring类xml

①在pom-xml中配置以下关于Spring的内容:

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

②刷新Maven,让其下载加载完成,不再是红色的字迹

Spring(一)

注意!!!我们要确保自己的仓库来自国内源,不然有时候会出现一些问题,那么如何检查配置呢?

Spring(一)

           5.3测试启动类

直接在java目录下建一个类,我们此处命名为start

Spring(一)

 当我们看到结果能够运行没有报错的话,那说明我们之前的步骤是没有问题的。

6.存入Bean

           6.1添加配置文件(非第一步省略此步骤)

当第一次配置好后,后续就不用再进行重复的配置了。

①找到相关位置:

Spring(一)

②配置文件,这里为了规范,我们就将其命名为spring-config.xml(当然其它名字也是可以的);

配置代码如下:(配置后,同样需要刷新Maven)

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

           6.2创建Bean对象

                        6.2.1创建Bean对象

实际上就是创建一个普通的java对象

Spring(一)

                        6.2.2将Bean对象注入到Spring

实质上就是bean通过配置文件注册到Spring中

①找到刚刚配置的Spring-config.xml文件,并输入以下代码:

Spring(一)

②解释一下id,和class的使用规则:

后面其实是通过bean的id来找到究竟是哪一个对象,这里的id名实际上是任意的,都可以,此处写为user是因为感觉更规范一点,而后面的class就是类名;且id可以!=class中的类名 

          6.3获取并使用Bean对象

                       6.3.1先得到Spring上下文对象

这里获取到bean对象的方法有两种,分别是:

①通过ApplicationContext来进行获取:

(1)格式:

Spring(一)

(2)特点:
ApplicationContext属于BeanFactory的子类。BeanFactory只提供了基础访问Bean的方法,而ApplicationContext除了拥有BeanFactory的所有功能之外,还提供了更多的方法来进行实现,比如对国际化的支持,资源访问的支持等等。
除此之外ApplicationContext采用的是饿汉模式,就是创建的时候一口气全部加载出来。

②通过BeanFactory来进行获取:

(1)格式:(这里划了杠并不是指不行。而是这个是之前旧版本用的,现在更新了,当然未来也有可能删除)

Spring(一)

 (2)特点:
而BeanFactory实质上是一种懒加载模式,是按需加载。

③异同点:

(1)异:

不同之处在各自的特点处已经进行了解释。

(2)同:

相同之处在于都可以实现从容器中获取Bean,都可提供了getBean()的方法。

④对他们的特点进行验证:

(1)对于ApplicationContext:(对于用户而言性能很高,虽然第一次加载开销大,但是后面都很流畅,很方便)

Spring(一)

 

(2)对于BeanFactory:(对于用户而言,性能很低)

Spring(一)

                       6.3.2再通过上下文提供的方法获取到Bean对象

①使用bean name来获取bean:

这种方法需要进行强制类型转化

Spring(一)

 ②根据bean type来获取bean:

这种方法有缺陷,当同一类型被注入到Spring多次时,就会报错

Spring(一)

 ③通过bean name和类型来获取:

这种方法是较为推荐的一种形式:

Spring(一)

                       6.3.3使用Bean对象

①格式:

类对象.方法

②演示:

Spring(一)

下期我们将继续介绍Bean相关内容哦,敬请期待