请选择 进入手机版 | 继续访问电脑版
MSIPO技术圈 首页 IT技术 查看内容

Spring 项目创建和使用2 (Bean对象的存取)

2023-07-13

目录

一、创建 Bean 对象

二、将Bean对象存储到 Spring容器中

三、创建 Spring 上下文(得到一个Spring容器)

 1. 通过在启动类中 ApplicationContext 获取一个 Spring容器

 2. 通过在启动类种使用 BeanFactory 的方式来得到 Spring 对象 (此时获取 Bean 的路径也要保持一致)

四、从 Spring 容器中获取到 Bean 对象(并使用Bean对象)

1. 通过名称(.xml文件中设置的 id )

     使用Applicationcontext 和 BeanFactory 的区别

  (1)所以二者的区别之一:

  (2)第二个区别:

 2. 通过类型的方式获取 Bean 对象

 3. 通过名称 + 类型的方式获取 Bean 对象

(1)先在.xml 文件中存储两个相同的 Bean 对象,然后再进行验证。

 四、什么是DI(依赖注入)


前言

    上一篇文章已经详细介绍了如何创建一个 Spring 项目,在创建好了 Spring 项目之后,就需要使用 Spring 容器存储和获取 Bean 对象了。 

    (Bean对象:在Java中,如果一个对象被使用多次,此时就可以成这个对象为 Bean 对象)

一、创建 Bean 对象

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

二、将Bean对象存储到 Spring容器中

    此时存储 Bean 对象是要依赖于xml配置文件的,里面要有一些配置信息,之后才能将 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"
       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.bit.service"></content:component-scan>
</beans>

    之后将上述代码复制到创建的配置文件 spring-config.xml 文件中

     在上述配置文件中添加下边代码:

 <!--将 bean对象(com.spring.demo.Student)存到spring容器中,他的名称叫做student -->
    <bean id="student" class="com.spring.demo.Student"></bean>

    此时就把一个 Bean 对象(Student类)存储到 Spring 中了,接下来就是取出 Bean 对象了。

三、创建 Spring 上下文(得到一个Spring容器)

    要想得到一个 Spring 容器有两种方式:

1.
ApplicationContext context = new
        ClassPathXmlApplicationContext("spring-config.xml");
2. 
//1. 得到Spring上下文对象
BeanFactory beanFactory =
        new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

 1. 通过在启动类中 ApplicationContext 获取一个 Spring容器

    此时需要注意:参数中的配置路径就是.xml 文件的名称,只有设置了这个文件名称,在程序运行的时候才会去这个文件中将 Bean 对象存储到 Spring 容器中。 

 2. 通过在启动类种使用 BeanFactory 的方式来得到 Spring 对象 (此时获取 Bean 的路径也要保持一致)

四、从 Spring 容器中获取到 Bean 对象(并使用Bean对象)

    获取 Bean 对象有三种方式:用的方法都是一样的,只是getBean()方法的传的参数不同

1. 通过名称获取
2. 通过类型获取
3. 通过名称 + 类型的方式获取

1. 通过名称(.xml文件中设置的 id )

//2. 从Spring容器中获取到Bean对象
        Student student = (Student) context.getBean("student");
        //3.使用Bean对象
        student.sayHi();

    此时需要  注意:getBean方法中的参数是 Bean 对象中的名称,此时需要和 spring-config.xml 文件中的 Bean 对象的 id 设置的名称保持相同。

    获取 Bean 对象之后我们可以使用 Student 类的sayHi方法证明以下  Bean 对象是否可以正常使用:

    使用BeanFactory的方式获取并使用 Bean对象

     使用Applicationcontext 和 BeanFactory 的区别

    此时再创建一个新的Teacher类,然后在Student 和 Teacher 类中都加上构造方法,如下代码:

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

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

     此时再去用 ApplicationContext 和 Beanfactory就可以看到以下运行结果:

    在App中并没有获取 Teacher 对象,但是此时却加载了 Teacher 类的构造方法,而BeanFatory只会在 getBean() 方法调用了之后才会加载初始化 Student 对象。

  (1)所以二者的区别之一:

    在使用 ApplicationContext 时是饿汉模式,当得到一个 Spring 容器的时候就初始化了所有的 Bean 对象的,但是使用 BeanFactory 时是懒汉模式(非必要不加载),也就是只有在获取 Bean 对象的时候才会去初始化这个对象。

    这也是一个历史性的原因,在早期内存是比较昂贵的时候,是没有很大的存储空间,在一开始就初始化很多 Bean 对象的,但是随着后来的内存的价格相对不是很昂贵了,此时也就有多余的内存空间来存储很多的 Bean 对象了,尽管 Spring 是一个容器,但是底层存储的 Bean 对象本质还是在内存上存储的。

ApplicationContext的优点和缺点:   一次 Spring 容器的加载,就会初始化里面的所有 Bean 对象,后续在读取 Bean 对象读取的就会非常快; 性能较高,但是同样的也会比较耗费内存。
BeanFactory的优点和缺点:  是在getBean() 方法调用之后才会加载初始化 Bean 对象,所以性能比较低; 但是节省内存。

  (2)第二个区别:

    BeanFactory 是 ApplicationContext 的一个子类,所以ApplicationContext是后来有的,基于 BeanFactory又拓展了新的功能特性。

    按下F4键之后,我们可以看到如下图:

 

 2. 通过类型的方式获取 Bean 对象

    虽然通过名称是可以获取到 Student 对象,但是需要强转之后才能获取,因为 getBean 方法的返回值是一个Object类型的,所以用 Student 类型的去接收返回值就需要强制类型转换;所以代码看起来好像不是很优雅,此时就可以通过对象的类型来获取一个 Bean 对象。

Student student = context.getBean(Student.class);//根据类型获取

    此时的运行结果如下:

     但是这种方式获取Bean 对象也是有问题的;如果此时有两个同类型的 Bean 对象,此时再去通过类型的方式来获取Bean 对象就会报如下图的错误,因为类型一样时,程序不知道该获取哪一个对象,所以此时虽然不用强转了,但是同类型的 Bean 对象只能有一个。

 3. 通过名称 + 类型的方式获取 Bean 对象

    首先注意一个问题:如果在 Spring 容器中存储同一个对象,存储两份,此时是有两个对象呢,还是只有一个对象,另一个对象的引用指向了第一个对象呢?

(1)先在.xml 文件中存储两个相同的 Bean 对象,然后再进行验证。

 运行结果:

     也就是说首先是允许存储两个相同的 Bean 对象的,但是此时结果是false,所以是在 Spring 容器中存储了两份 Bean 对象的。(每一次存储 Bean 对象的时候,不会因为类型相同就只创建一个对象)

    根据名称 + 类型的方式来获取Bean 对象也是可以的,如下图结果:

 四、什么是DI(依赖注入)

Student student = context.getBean("student",Student.class);//根据类型获取

    上述代码就是依赖注入,就是DI,上一篇文章讲到IoC是一种思想,DI就是它的一种具体的实现方式,所以上面代码就是在程序运行的过程中动态的将 student 对象动态注入到当前运行的动态类中。

相关阅读

热门文章

    手机版|MSIPO技术圈 皖ICP备19022944号-2

    Copyright © 2024, msipo.com

    返回顶部