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

目录

一、创建 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 对象

Spring 项目创建和使用2 (Bean对象的存取)_第1张图片

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

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

    此时存储 Bean 对象是要依赖于xml配置文件的,里面要有一些配置信息,之后才能将 Bean对象存储到 Spring 容器中,如下图:

Spring 项目创建和使用2 (Bean对象的存取)_第2张图片



    

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

Spring 项目创建和使用2 (Bean对象的存取)_第3张图片

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

 
    

    此时就把一个 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 容器中。 

Spring 项目创建和使用2 (Bean对象的存取)_第4张图片

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

Spring 项目创建和使用2 (Bean对象的存取)_第5张图片

四、从 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 对象是否可以正常使用:

Spring 项目创建和使用2 (Bean对象的存取)_第6张图片

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

Spring 项目创建和使用2 (Bean对象的存取)_第7张图片

     使用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就可以看到以下运行结果:

Spring 项目创建和使用2 (Bean对象的存取)_第8张图片

Spring 项目创建和使用2 (Bean对象的存取)_第9张图片

    在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又拓展了新的功能特性。

Spring 项目创建和使用2 (Bean对象的存取)_第10张图片

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

 Spring 项目创建和使用2 (Bean对象的存取)_第11张图片

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

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

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

    此时的运行结果如下:

Spring 项目创建和使用2 (Bean对象的存取)_第12张图片

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

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

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

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

Spring 项目创建和使用2 (Bean对象的存取)_第13张图片

 运行结果:Spring 项目创建和使用2 (Bean对象的存取)_第14张图片

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

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

Spring 项目创建和使用2 (Bean对象的存取)_第15张图片

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

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

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

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