您现在的位置是:首页 >学无止境 >Spring 创建和使用网站首页学无止境

Spring 创建和使用

Node_Hao 2023-07-02 16:00:03
简介Spring 创建和使用


Spring 是一个包含了众多工具方法的 IoC 容器 , 既然是容器那么一定具备两个最基本的功能:

  • 将对象存储到容器(Spring) 中;
  • 从容器中将对象取出来.

什么是 Bean ?

在 Java 中对象也叫 Bean , 所以以后遇到对象就以 Bean 著称

初学 java 时我们都知道 , java 的图标是一杯咖啡 , 那么 bean 就可以当做咖啡豆.

bean 是一种特殊的 可重用的类 , 具有以下特征:

  • 提供一个无参构造函数
  • 需要被序列化且实现了 Serializable 接口
  • 有一系列可读属性 , 且一般是 private 的.
  • 有一系列的 Setter 和 getter 方法.

可以想象有一个箱子 , 内部被分成好几部分 , 每一部分存放指定的物品 , 工人可以从箱子中取出物品 , 也可以放入物品后封箱发送快递 , 其中 箱子就可以看做是 bean , 存取操作就是 Getter 和 Setter , 物品就是属性 , 封箱发送就是序列化和传输.

1. 创建 Spring 项目

接下来使用 Maven 来创建一个 Spring 项目 , 大致流程和创建 Servlet 类似 , 总共分为以下三步:

  1. 创建一个普通的 Maven 项目
  2. 添加 Spring 框架支持(Spring-context , spring-beans).
  3. 添加启动类

1.创建一个 Maven 项目

选择 Maven 之后直接点击 next 即可.

配置好路径之后直接点击 Finsh 即可.

文件显示如下图所示则初始化完毕

image-20230501212620237

2. 添加 Spring 依赖

1.配置 Maven 国内源

添加 Spring 依赖 , 为了保证项目可以方面的下载 , 我们需要配置Maven 国内源.

但 IDE 有个很反人类的操作 , 我们需要配置两次 seting (一个是当前配置文件 , 一个是新项目的配置文件)

当前配置文件:

新配置文件:

配置文件只需打两个对钩 , 最下面的对钩不选.

image-20230501212652777

通过复制 User seting file 路径找到settings.xml , 如果没有settings.xml . 可以直接下载我分享的配置.

settings.xml

image-20230501212708787

用 vscode 或 notepad++ , 打开该文件 , 找到 mirrors , 添加阿里的国内源.

   <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <mirrorOf>central</mirrorOf>        
      </mirror>

image-20230501212724934

重新下载 jar 包

点击Maven中的Reload.

image-20230501212732106

继续配置 新配置文件 中的 Maven , 步骤与上述一致.

2.添加 Maven 依赖

Maven Repository: spring (mvnrepository.com)

在 Maven 仓库中找到 spring.

image-20230501212735689

最好使用 5.xxx 的版本 , 因为 6.xx 版本对 jdk 的最低要求是 17.

image-20230501212742200

在 pom.xml 中引入 spring 依赖 , 并记得 Reload.

image-20230501212748611

如果出现如下目录代表下载完毕.

image-20230501212753805

3.添加启动项

启动类是为之后操作 spring 做准备的.

image-20230501212758783


2.存储Bean对象

存储 Bean 分为以下 2 步:

  1. 创建一个Bean (在 java 中一个对象如果被使用多次 , 就可以称之为 Bean)
  2. 将创建的 Bean 注册到 Spring 容器中.

1.创建 Bean

public class Student {
    private void sayHi(){
        System.out.println("hi student");
        
    }
}

2.注册 Bean

在创建好的项目中添加 Spring 配置文件 spring-config.xml , 将此文件放到 resources 的根目录下.

image-20230501212811209

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 中即可 , 具体操作是在 中添加如下配置:

image-20230501212816356

3.获取并使用 Bean 对象

从 Spring 容器中读取到 Bean

  1. 得到 Spring (上下文)对象 , 因为对象都交给 Spring 管理了 , 所以获取对象要从 Spring 中获取 , 那么就需先得到 Spring 的上下文.
  2. 通过 Spring 上下文 , 获取到一个指定的 Bean 对象
  3. 使用 Bean 对象.

1. 得到 Spring 对象

常见方式有两种:
ApplicationContext context = 
  new ClassPathXmlApplicationContext("spring-config.xml"); 
BeanFactory beanFactory = 
  new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

ApplicationContext 与 BeanFactory 获取对象的效果是一样的 , 只不过 Application 是 BeanFactory 的子类 , 它们的区别如下:

image-20230501212821111

  • 在继承和功能方面: Spring 容器有两个顶级的接口: BeanFactory 和 ApplicationContext , 其中 BeanFactoty 提供最基础的访问容器的功能 ,

    而 ApplicationContext 除了继承 BeanFactory 所以功能之外 , 还添加了对国际化支持 , 资源访问 , 以及事件传播等方面的支持.

  • 从性能方面来讲: ApplicationContext 会一次性加载并初始化所有的 Bean 对象(饿汉模式) , 而 BeanFactory 则是需要哪个才去加载哪个 , 因此更加轻量.

ClassPathXmlApplicationContext 属于 ApplicationContext 的子类 , 拥有 ApplicationContext 的所有功能 , 是通过 xml 的配置来获取所有的 Bean 容器.

image-20230501212828319

2. 获取 Bean 对象

Bean 的三种获取方式
  1. 根据名称
Student student = (Student) beanFactory.getBean("student");

Tips: Bean 的 Id 要一一对应.

image-20230501212832799

  1. 根据类名
Student student = context.getBean(Student.class);

根据类名获取 Bean 对象看似简单 , 但如果 Spring 中一个类型存储了多个实例 , 那么使用类型获取 Bean 就会报错.

image-20230501212841897

image-20230501212847482

  1. 根据类型和名称一起获取
Student student  = context.getBean("student", Student.class);

第三种方式看似与第一种相似 , 但第一种相对更加暴力 , 如果通过类名找不到 Bean , 依然坚持强制类型转换 , 就会空指针异常. 而第三种方式更加优雅.

3.使用 Bean 对象

代码示例:

spring-config.xml 中注册的 bean 并如下:

    <bean id="stu" class="com.spring.demo.Student"></bean>

    <bean id="student" class="com.spring.demo.Student"></bean>

    <bean id="teacher" class="com.spring.demo.Teacher"></bean>

Student 类中代码:

public class Student {
    public Student(){
        System.out.println("do student init");
    }
    public void sayHi(){
        System.out.println("hi student");

    }
}

Teacher 类中的代码:

public class Teacher {
    public Teacher(){
        System.out.println("do teacher init");
    }
    public void sayHi(){
        System.out.println("hi teacher");
    }
}

通过 ApplicationContext 获取 Spring 对象 , 并使用 bean 对象.

public class App {
    public static void main(String[] args) {
        //1.得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2. Spring 容器中获取到 bean 对象
        Student student  = context.getBean("student", Student.class);
        //3.使用 Bean 对象
        student.sayHi();
    }
}

通过运行结果可以看出 , ApplicationContext 会初始化容器中所有 Bean 对象.

image-20230501212852709

通过 BeanFactory 获取 Spring 对象 , 并使用 bean 对象

public class App2 {
    public static void main(String[] args) {
        // 1.得到 Spring 上下文对象
        BeanFactory beanFactory =
                new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
        //2. 从 Spring 容器中获取 bean 对象
        Student student = (Student) beanFactory.getBean("student");
        //3. 使用 Bean
        student.sayHi();
    }
}

通过运行结果可以看出 , BeanFactory 只有调用 getBean 才会加载对应的 Bean对象.

image-20230501212858292

类型相同的 bean 对象 , 实例化一样吗?
public class App {
    public static void main(String[] args) {
        //1.得到 Spring 上下文对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2. Spring 容器中获取到 bean 对象
        Student student  = context.getBean("student", Student.class);
        Student stu = context.getBean("stu", Student.class);

        System.out.println("student == stu -->" + (student == stu));
    }
}

通过运行结果 , 我们可以得知 , 每一个存储在 Spring 中的bean , Spring 都会单独的为它们创建一个 bean 对象 , 不会因为类型相同就使用同一个对象.

image-20230501212904201

总结

Spring 的操作流程如下:

在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。