JavaEE 突击 3 - Spring 创建和使用

Spring 创建和使用

  • 一 . 创建 Spring 项目
    • 1.1 创建一个 Maven 项目
    • 1.2 添加 Spring 框架依赖
    • 1.3 添加启动类
  • 二 . 将 Bean 对象存储到 Spring
    • 2.1 创建 Bean 对象
    • 2.2 将 Bean 存储到 Spring
    • 2.3 从 Spring 中取出 Bean 对象
      • 2.3.1 先得到 Spring 对象(Spring 上下文对象)
      • 2.3.2 从 Spring 上下文当中取出对象
      • 2.3.3 使用 bean (非必须)
    • 2.4 特殊情况
      • 2.4.1 xml 配置文件一定要写正确
      • 2.4.2 bean 标识一定要写正确
    • 2.5 getBean 方法的更多用法
      • 2.5.1 `getBean(String s)`
      • 2.5.2 `getBean(class aclass)`
      • 2.5.3 `getBean(String s , class aclass)`
    • 2.6 面试题 : ApplicationContext VS BeanFactory
  • 三 . 总结

大家好 , 这个专栏给大家介绍一下 Java 家族的核心产品 - SSM 框架

Java 语言能走到现在 , 仍然屹立不衰的原因 , 有一部分就是因为 SSM 框架的存在

接下来 , 博主会带大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相关知识点

并且带领大家进行环境的配置 , 让大家真正用好框架、学懂框架

在这里插入图片描述

目标 :

  1. Spring (Core) 项目创建
  2. 将对象存储到 Spring 中
  3. 将对象从 Spring 里面取出

在 Spring 里面 , 把对象叫做 Bean

一 . 创建 Spring 项目

我们接下来用 Maven 创建一个 Spring 项目

  1. 创建一个 Maven 项目
  2. 添加 Spring 框架支持 (spring-context : 上下文 spring-beans : 对象)
  3. 添加启动类

我们这里使用的环境是 IDEA 2021.2 社区版 , JDK 1.8

1.1 创建一个 Maven 项目

JavaEE 突击 3 - Spring 创建和使用_第1张图片
JavaEE 突击 3 - Spring 创建和使用_第2张图片
JavaEE 突击 3 - Spring 创建和使用_第3张图片

1.2 添加 Spring 框架依赖

添加两个引用 :

  1. spring - content : spring 上下文
  2. spring - beans : spring 对象

这一步很简单 , 我们只需要把下面这段代码复制到 pom.xml 里面
当然也可以去中央仓库里面找

<dependencies>
  <dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-contextartifactId>
    <version>5.2.3.RELEASEversion>
  dependency>
  <dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-beansartifactId>
    <version>5.2.3.RELEASEversion>
  dependency>
dependencies>

在这一步 , 我们一定要保证修改镜像源为国内的 , 要不然 超级大概率 会失败
JavaEE 突击 3 - Spring 创建和使用_第4张图片
我们还可以通过左侧来检验下载是否成功
JavaEE 突击 3 - Spring 创建和使用_第5张图片
我们点击上面的刷新按钮
JavaEE 突击 3 - Spring 创建和使用_第6张图片
JavaEE 突击 3 - Spring 创建和使用_第7张图片
但是我们下载的依赖只有 spring - content 和 spring - beans 啊 ? 这怎么多出来几个 ?

是这样的 , 我们的 spring - content 和 spring - beans 也是需要额外的依赖包的 , 如果单纯使用 spring - content 和 spring - beans , 也需要把它的几个依赖包导入进来 , 其实就相当于结婚的嫁妆

1.3 添加启动类

实际上就是添加 main 方法
那我们之前写 Servlet 程序 , 也没有 main 方法啊 ?

实际上 , Servlet 是隐藏 main 方法的 , 是不展示给用户的

我们这里的 Spring 程序就是一个最简单的程序 , 还是需要 main 方法的
在 java 目录底下新建一个类
JavaEE 突击 3 - Spring 创建和使用_第8张图片
JavaEE 突击 3 - Spring 创建和使用_第9张图片

二 . 将 Bean 对象存储到 Spring

存储 Bean 对象需要两步 :

  1. 存储 Bean 之前 , 先得有 Bean , 所以先创建一个 Bean 对象
  2. 将创建的 Bean 注册到 Spring 容器中

2.1 创建 Bean 对象

JavaEE 突击 3 - Spring 创建和使用_第10张图片
JavaEE 突击 3 - Spring 创建和使用_第11张图片

public class User {
    // 普通的类,普通的方法
    public void sayHi() {
        System.out.println("say hi!");
    }
}

JavaEE 突击 3 - Spring 创建和使用_第12张图片

2.2 将 Bean 存储到 Spring

在 Spring 里面 , 并不是所有的 Bean 都会被存储到 Spring 里面 , 只有需要的才会存储到 Spring 里面
而这个存储 , 也不是真正意义上的存储 , 只是告诉 Spring , 这个 Bean 需要托管给 Spring
那么我们接下来需要在 resources 里面新建一个文件 , 叫做 spring-config.xml (这个名字大家也可以起别的 , 这里推荐大家起这个就行)
JavaEE 突击 3 - Spring 创建和使用_第13张图片
JavaEE 突击 3 - Spring 创建和使用_第14张图片
然后把这段代码复制进去


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

JavaEE 突击 3 - Spring 创建和使用_第15张图片
目前的只是准备工作 , 我们接下来才是将 Bean 存储到 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--  注册一个对象到 Spring-->
    <!--  先写一个 bean 标签  -->
    <bean id="user" class="User"></bean>

</beans>

JavaEE 突击 3 - Spring 创建和使用_第16张图片
里面的 class 也是需要写包名的 , 但是因为我们没创建包 , 所以就没写
那么我们可以改一下 , 把代码放到包里面
JavaEE 突击 3 - Spring 创建和使用_第17张图片
目前为止 , 我们只是声明存储对象到 Spring 里面了 , 并不是真正存储到 Spring 里面了 , 正常情况下 , 我们的 Spring 是懒加载 , 在启动 Spring 的时候 , 他并不会立即存储 Spring 对象 , 但是从广义上来理解 , 我们的 Spring 已经存储这个对象了

2.3 从 Spring 中取出 Bean 对象

2.3.1 先得到 Spring 对象(Spring 上下文对象)

对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那么就得先得到 Spring 的上下文。
Spring 上下文对象可使用 ApplicationContext
JavaEE 突击 3 - Spring 创建和使用_第18张图片
JavaEE 突击 3 - Spring 创建和使用_第19张图片
JavaEE 突击 3 - Spring 创建和使用_第20张图片
JavaEE 突击 3 - Spring 创建和使用_第21张图片

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // 1. 得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
    }
}

2.3.2 从 Spring 上下文当中取出对象

JavaEE 突击 3 - Spring 创建和使用_第22张图片
先不管选哪个 , 我们注意 : getBean 返回值是 Object , 但是我们的对象是 User 类型 , 所以我们需要强转一下
JavaEE 突击 3 - Spring 创建和使用_第23张图片
JavaEE 突击 3 - Spring 创建和使用_第24张图片
JavaEE 突击 3 - Spring 创建和使用_第25张图片
JavaEE 突击 3 - Spring 创建和使用_第26张图片

import com.ethan.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // 1. 得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");

        // 2. 从 Spring 里面获取对象
        // User user = new User();//在当前类当中创建 User 对象,原始方式不推荐[存在代码耦合]
        User user = (User)context.getBean("user");//只有第一次执行,才会创建.因为是单例模式,创建过后会一直留着,下次用直接拿走
    }
}

2.3.3 使用 bean (非必须)

之前怎么使用 , 现在就怎么使用
JavaEE 突击 3 - Spring 创建和使用_第27张图片

import com.ethan.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // 1. 得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");

        // 2. 从 Spring 里面获取对象
        // User user = new User();//在当前类当中创建 User 对象,原始方式不推荐[存在代码耦合]
        User user = (User)context.getBean("user");//只有第一次执行,才会创建.因为是单例模式,创建过后会一直留着,下次用直接拿走

        // 3. 使用 bean
        user.sayHi();//跟以前一样
    }
}

运行一下 :
JavaEE 突击 3 - Spring 创建和使用_第28张图片

2.4 特殊情况

2.4.1 xml 配置文件一定要写正确

我们之前说 resources 目录底下的配置文件推荐大家使用 spring-config.xml
那么这个名字其实叫什么都行
JavaEE 突击 3 - Spring 创建和使用_第29张图片
那我们改成 spring 看看还能不能成功
JavaEE 突击 3 - Spring 创建和使用_第30张图片
成功了
JavaEE 突击 3 - Spring 创建和使用_第31张图片
但是这种虽然合法但是不规范
那我们试一下这种情况 :
配置文件名称叫 spring-config.xml , 我们的代码里面写成了 spring.xml
JavaEE 突击 3 - Spring 创建和使用_第32张图片
那么运行一下 , 看看会不会运行起来
JavaEE 突击 3 - Spring 创建和使用_第33张图片
那么我们帮大家排查一下错误
JavaEE 突击 3 - Spring 创建和使用_第34张图片
JavaEE 突击 3 - Spring 创建和使用_第35张图片
那么就是 spring.xml 没有找到
因为我们的配置文件叫 spring-config.xml , 不是 spring.xml , 所以就会报错
而且下面还有行数提醒
JavaEE 突击 3 - Spring 创建和使用_第36张图片

2.4.2 bean 标识一定要写正确

JavaEE 突击 3 - Spring 创建和使用_第37张图片
我们运行一下
JavaEE 突击 3 - Spring 创建和使用_第38张图片
JavaEE 突击 3 - Spring 创建和使用_第39张图片

2.5 getBean 方法的更多用法

2.5.1 getBean(String s)

我们之前介绍的方法 :
getBean(String s) : 根据名称来获取 bean 对象
这种方法需要进行强转 , 但是他有一个好处 : 我们注册多个 bean , 他会精准定位
比如 :
JavaEE 突击 3 - Spring 创建和使用_第40张图片
那么我们的这种方法能正常识别吗 ?
JavaEE 突击 3 - Spring 创建和使用_第41张图片
那么这种情况还是挺常见的 : 在公司协同开发 , 张三使用了 user , 李四不知道 , 李四也使用了 user , 这样就产生了重复
原则上来说 , 一个 key 只能出现一次 , 我们就可以把这个第二个 user 改成 user2
JavaEE 突击 3 - Spring 创建和使用_第42张图片
JavaEE 突击 3 - Spring 创建和使用_第43张图片
那有的人就问了 , 怎么证明 User 和 User2 是不一样的呢 ? 因为他们打印的结果相同啊 , 就会有人以为他们是不是一个东西起了两个名字啊 , 那很好证明
JavaEE 突击 3 - Spring 创建和使用_第44张图片
那么我们还可以去证明 user 是不是单例模式
JavaEE 突击 3 - Spring 创建和使用_第45张图片
为 true 就代表是单例模式 , 因为 Spring 中创建出一个对象就会一直存储到 Spring 中 , 方便后续使用 , 就不用再去重新创建了

2.5.2 getBean(class aclass)

getBean(class aclass) : 根据类型获取 bean 对象

import com.ethan.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // 1. 得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");

        // 2. 从 Spring 里面获取对象
        // 2.1 根据一个 String 参数获取 bean
        //User user = (User)context.getBean("user");//只有第一次执行,才会创建.因为是单例模式,创建过后会一直留着,下次用直接拿走

        // 2.2 根据一个 Class 参数获取 bean
        User user = context.getBean(User.class);//这种方法不用强转了

        // 3. 使用 bean
        user.sayHi();//跟以前一样
    }
}

JavaEE 突击 3 - Spring 创建和使用_第46张图片
这种情况是 spring-config.xml 里面只有一个 bean 对象
那么有两个呢 ?
JavaEE 突击 3 - Spring 创建和使用_第47张图片
再运行一下 :
JavaEE 突击 3 - Spring 创建和使用_第48张图片
看一下异常
JavaEE 突击 3 - Spring 创建和使用_第49张图片
JavaEE 突击 3 - Spring 创建和使用_第50张图片
我们再看一下 spring-config.xml
JavaEE 突击 3 - Spring 创建和使用_第51张图片
JavaEE 突击 3 - Spring 创建和使用_第52张图片

import com.ethan.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // 1. 得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");

        // 2. 从 Spring 里面获取对象
        // 2.1 根据一个 String 参数获取 bean
        /*User user = (User)context.getBean("user");
        User user1 = (User)context.getBean("user");
        User user2 = (User)context.getBean("user2");

        System.out.println("user:" + user);
        System.out.println("user1:" + user1);
        System.out.println("user2:" + user2);
        System.out.println("user == user1 -> " + (user == user1));
        System.out.println("user == user2 -> " + (user == user2));//为true说明他们地址相同,是一个对象;为false说明地址不同,不是同一个对象*/

        // 2.2 根据一个 Class 参数获取 bean
        User user = context.getBean(User.class);//这种方法不用强转了

        // 3. 使用 bean
        user.sayHi();//跟以前一样
    }
}

2.5.3 getBean(String s , class aclass)

getBean(String s , class aclass) : 这种方法更加稳健 , 虽然他比第一种也没差哪去 , 不过如果是第一种方法 , 万一内容为 null , 对 null 进行强转就会出现问题 , 但是你通过这种方法的话 , 整体就会返回一个 null , 就不存在空指针问题了

import com.ethan.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // 1. 得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");

        // 2. 从 Spring 里面获取对象
        // 2.1 根据一个 String 参数获取 bean
        /*User user = (User)context.getBean("user");
        User user1 = (User)context.getBean("user");
        User user2 = (User)context.getBean("user2");

        System.out.println("user:" + user);
        System.out.println("user1:" + user1);
        System.out.println("user2:" + user2);
        System.out.println("user == user1 -> " + (user == user1));
        System.out.println("user == user2 -> " + (user == user2));//为true说明他们地址相同,是一个对象;为false说明地址不同,不是同一个对象*/

        // 2.2 根据一个 Class 参数获取 bean
        //User user = context.getBean(User.class);//这种方法不用强转了

        // 2.3 根据 String(bean id) 和 Class 参数获取 bean
        User user = context.getBean("user",User.class);//更加的稳健
        // 3. 使用 bean
        user.sayHi();//跟以前一样
    }
}

JavaEE 突击 3 - Spring 创建和使用_第53张图片
同样的方式 , 我再去读 user2 也是没问题的
JavaEE 突击 3 - Spring 创建和使用_第54张图片

2.6 面试题 : ApplicationContext VS BeanFactory

Spring 上下文对象可使用 ApplicationContext , 我们还可以使用 BeanFactory (ApplicationContext的父类) 来作为 Spring 的上下文
JavaEE 突击 3 - Spring 创建和使用_第55张图片
不过 IDEA 已经不推荐我们使用这种方法了
JavaEE 突击 3 - Spring 创建和使用_第56张图片

import com.ethan.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class App {
    public static void main(String[] args) {
        // 1. 获取上下文对象
        BeanFactory context = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
        // 2. 从 Spring 里面获取对象
        User user = context.getBean("user2", User.class);
        // 3. 使用方法
        user.sayHi();
    }
}

运行一下 :
JavaEE 突击 3 - Spring 创建和使用_第57张图片
那么既然他们都能运行成功 , 那有什么区别呢 ?

  1. 共同点 : 都是用来获取 Spring 的上下文对象
  2. 不同点 :
  3. 继承关系和功能 : ApplicationContext 属于 BeanFactory 的子类 , ApplicationContext 具备了 BeanFactory 所有的功能 , 而 BeanFactory 只具备最基础访问 Bean 的功能 . Application 还具备了更多的能力 , 比如 : 国际化支持 资源访问支持 事件传播 …
  4. 从性能方面来说 , ApplicationContext 是一次性加载并初始化所有的 Bean 对象 , 而 BeanFactory 是按需加载 , 需要使用 Bean 的时候才去加载

三 . 总结

  1. 操作容器之前,先要有容器,所以先要得到容器 , 就需要我们创建 Spring 项目
  2. 存对象
    1. 创建 Bean(普通类)。
    2. 将 Bean 注册(配置)到 spring-confing.xml 中。
  3. 取对象
    1. 得到 Spring 上下文,并读取到 Spring 的配置文件。
    2. 获取某⼀个 Bean 对象。
    3. 使用 Bean 对象。

JavaEE 突击 3 - Spring 创建和使用_第58张图片

你可能感兴趣的:(JavaEE,进阶,spring,java-ee,java)