您现在的位置是:首页 >技术交流 >从 Spring 的创建到 Bean 对象的存储、读取网站首页技术交流

从 Spring 的创建到 Bean 对象的存储、读取

@Main. 2024-06-17 10:15:01
简介从 Spring 的创建到 Bean 对象的存储、读取

目录

创建 Spring 项目:

1.创建一个 Maven 项目:

 2.添加 Spring 框架支持:

3.配置资源文件:

4.添加启动类:

Bean 对象的使用:

1.存储 Bean 对象:

1.1 创建 Bean:

1.2 存储 Bean 到容器内:

2.获取 Bean 对象:

2.1 创建 Spring 上下文:

2.2 获取指定 Bean 对象:

ApplicationContext 和 BeanFactory 的区别:

ApplicationContext:

BeanFactory:

总结:

三种常用的 getBean :

根据 id 获取:

对象类型获取:

id + 对象类型获取:

总结



创建 Spring 项目:

        创建一个 Spring 项目分为四步:

  1.  创建一个普通 Maven 项目;
  2.  添加 Spring 框架支持;
  3.  配置资源文件;
  4.  添加启动类;

1.创建一个 Maven 项目:

前提声明:个人尽量使用 idea2021,因为2022版之后的相关插件是收费的;

 2.添加 Spring 框架支持:

        将这段配置依赖添加到 Spring 项目的 pom.xml 文件中:刷新下载到本地仓库

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.24</version>
        </dependency>
    </dependencies>

3.配置资源文件:

        在 resources 包中创建一个 xxx.xml 文件,再把 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">
    <content:component-scan base-package="com.spring.demo"></content:component-scan>
</beans>

4.添加启动类:

        在 java 文件下创建一个类,专门用来启动测试:

public class School {
    public static void main(String[] args) {

    }
}


Bean 对象的使用:

1.存储 Bean 对象:

        原理:Spring 框架有 spring-context 来管理 spring 上下文,还有 spring-beans 来管理对象的模块;

        什么是 Bean对象?项目中重复使用的对象都可以视为 Bean 对象,存储 Bean 对象也就是把项目所需的对象放入 Spring 容器中;

1.1 创建 Bean:

        现在创建了一个普通的 Student 类,其自带一个 sayHi() 方法,由于以后我还要频繁使用这个类,那么就可以将其视为一个 Bean:

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

1.2 存储 Bean 到容器内:

        存储bean也相当于“声明”的作用,先打开刚才在 resources包里创建的 spring-config.xml 配置文件:

存储 Bean 的格式:

<bean id="" class=""><bean>

如果 bean 在多级包内,class属性设置时就要注意路径;

现在将 Student 这个类作为 bean 添加进去:注意路径

<!--    将Bean对象(com.spring.demo.com.spring.demo.Student)
存到 Spring容器中,它的 id 为 student-->
    <bean id="student" class="com.spring.demo.Student"></bean>

2.获取 Bean 对象:

        获取 bean 对象分为三步:

  1. 得到 Spring 上下文对象:因为 Bean 对象交给了 Spring 来管理,所以得先得到 Spring 才能有权限操作容器;
  2. 通过 Spring 上下文获取容器内的 Bean 对象;
  3. 使用 Bean 对象;

2.1 创建 Spring 上下文:

        这里需要了解两个接口:ApplicationContext BeanFactory

        语法:

ApplicationContext context = 
                new ClassPathXmlApplicationContext("spring-config.xml");
 BeanFactory beanFactory =
                new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

2.2 获取指定 Bean 对象:

        这里借助 ApplicationContext 来演示:

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

至此 Spring 的创建、Bean 的存储和获取已经做了基本介绍;


ApplicationContext 和 BeanFactory 的区别:

        在上述代码中再添加一个 Teacher 类作为一个新的 Bean,添加到容器中:

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

    public void sayHi() {
        System.out.println("hi teacher");
    }
}
    <bean id="student" class="com.spring.demo.Student"></bean>
    <bean id="teacher" class="com.spring.demo.Teacher"></bean>

此时我们的容器中有两个 Bean:一个是Student、一个是Teacher;

        分别使用 ApplicationContext 和 BeanFactory 来操作:都只尝试获取容器中 Student 这个 Bean,来看看它们的效果有什么不同.

ApplicationContext:

        原代码不用变: 

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

BeanFactory:

        创建一个新的启动类:School2,获取 Spring 上下文和 ApplicationContext 不一样,其他也不用变。

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

         对比运行结果,明明它们两个都时获取和使用 id 为 “student” 的 Bean 对象,ApplicationContext 对于上下文却把 Teacher 也拿了出来,BeanFactory 只拿到了 Student;

总结:

相同点:

  • ApplicationContext 和 BeanFactory 都是获取容器中Bean对象的;

不同点:

  •  ApplicationContext 是一次性加载并初始化容器里的所有 Bean 对象(饿汉模式),而 BeanFactory 是需要哪个才去加载哪个(懒汉模式);
  • ApplicationContext 其实是 BeanFactory 的子类,子类不仅继承了父类的所有功能外,还拥有自己独特的功能;而ClassPathXmlApplicationContext 又属于 ApplicationContext的子类;
  • BeanFactory 也是最早被设计出来的,设计之初由于机器硬件造价昂贵,就只加载需要的对象;而 ApplicationContext 是之后设计出来的,人们为了尽可能提高效率,就想到一次性加载出所有 Bean 对象;


三种常用的 getBean :

        getBean() 方法有很多重载,对比以下常用的三种:

  1. 根据 id 获取;
  2. 对象类型获取;
  3. id,对象类型获取;

根据 id 获取:

    <bean id="student" class="com.spring.demo.Student"></bean>
    <bean id="teacher" class="com.spring.demo.Teacher"></bean>
        // 2.获取指定 Bean 对象
        Student student = (Student) context.getBean("student");
        Teacher teacher = (Teacher) context.getBean("teacher");

这种方式显然比较粗暴,不可取,存在强转;另外如果通过id获取的对象为null,也会出现异常;

对象类型获取:

    <bean id="student" class="com.spring.demo.Student"></bean>
    <bean id="teacher" class="com.spring.demo.Teacher"></bean>
        // 2.获取指定 Bean 对象
        Student student = context.getBean(Student.class);
        Teacher teacher = context.getBean(Teacher.class);

这种方式虽然不粗暴,但存在一个问题:

        当同一类型的 Bean 在容器中注册了两次,编译器就会报 NoUniqueBeanDefinitionException 异常;

id + 对象类型获取:

        这种方式安全性较高;

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

    <bean id="teacher" class="com.spring.demo.Teacher"></bean>
        // 2.获取指定 Bean 对象
        Student student = context.getBean("student2",Student.class);
        Teacher teacher = context.getBean("teacher",Teacher.class);

思考:
        既然刚才提到了同一个类型可能在容器中注册多次,虽然它们只是 id 不同,那它们指向的是否为同一块空间呢?

        代码验证一下:

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

    <bean id="teacher" class="com.spring.demo.Teacher"></bean>
public class School {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
       
        Student student1 = context.getBean("student", Student.class);
        Student student2 = context.getBean("student2", Student.class);
       
        System.out.println(student1 == student2);
        System.out.println(student1.equals(student2));
    }
}

于是证明它们本身就是不同的对象的引用;


总结:

Spring 项目的创建及 Bean 的基本使用流程:

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