[spring学习]2、spring基本使用及源码分析

目录

spring的配置及使用

spring的配置

spring的使用

执行流程的解释

spring执行源码分析

基本说明

源码分析

xml文件中的配置信息存放位置 

单例对象池

细节说明

总结 


spring的配置及使用

        下面来对如何使用spring来获取bean进行讲解

spring的配置

        在上一篇文章中,我们导入包之后就能够进行使用,要使用spring,我们需要建一个基于spring的xml文件。在idea中右键src,然后点击new->XML Configuration File->Spring Config

        创建xml文件后进行配置

        选择Create new application context

[spring学习]2、spring基本使用及源码分析_第1张图片

        选择自己创建的xml文件,然后点击ok

[spring学习]2、spring基本使用及源码分析_第2张图片

        设置好之后xml的警告消失

[spring学习]2、spring基本使用及源码分析_第3张图片

         这样,我们就配置好了,下面来对spring进行基本使用


spring的使用

        这里先不做分析,直接使用。我通过创建单元测试来对spring进行测试及使用,下面直接上代码,然后对代码进行解释。

这个是一个简单的javaBean

public class People {
    private Integer id;
    private String name;
    private String gender;

    public People() {
    }

    public People(Integer id, String name, String gender) {
        this.id = id;
        this.name = name;
        this.gender = gender;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "People{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

这个是xml配置文件信息




    
    
        
        
        
        
    

单元测试


    @Test
    public void t1(){
        //得到spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("csdn.xml");
        //通过id来获取xml文件配置的bean
        Object people = applicationContext.getBean("people");
        System.out.println(people);
    }

控制台输出

[spring学习]2、spring基本使用及源码分析_第4张图片


执行流程的解释

        如果是第一次使用spring,上面的代码应该是很懵逼的,现在我来梳理一下,我对测试方法中的代码进行梳理,xml文件中的后面会详细说明。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("csdn.xml");

        这行代码就是通过类路径的方式来获取xml文件,然后对xml文件进行解析。ClassPathXmlApplicationContext就是ApplicationContext的一个实现类,除了这个还有其他的,下面进行给出

[spring学习]2、spring基本使用及源码分析_第5张图片

        通过不同的实现类,我们就可以通过不同的方法来创建spring容器。 

Object people = applicationContext.getBean("people");

        这行代码就将我们在xml文件中配置的id为people的对象进行返回,默认是单例的。返回的就是一个Object对象,当然,getBean还有很多的重载方法,通过getBean我们就可以获取在spring在容器中的对象。


spring执行源码分析

        下面通过debug的方式来对spring的执行流程进行分析

基本说明

        在分析源码之前,先来对spring容器进行简单说明。ioc,这个是控制反转的意思,就是将对象的创建权交给spring来管理。这个是spring的核心,spring来管理对象的创建,而程序员只需要专注于业务。

        spring是如何实现的呢?为什么在xml文件中配置的bean可以通过一个getBean就直接获取到?先来简单解释,当我们创建spring容器时,传入了xml文件的路径,这样spring在创建时就会扫描xml中的配置信息,根据配置的不同来创建对象(如果是单例的且不是懒加载),spring容器会将对象创建并保存在容器中,于是我们通过getBean就可以获取到配置的bean。

源码分析

        我们在创建spring容器时下一个断点,然后进行debug

[spring学习]2、spring基本使用及源码分析_第6张图片

[spring学习]2、spring基本使用及源码分析_第7张图片


xml文件中的配置信息存放位置 

        我们已经成功创建了spring容器,点开容器,对里面属性进行分析 

[spring学习]2、spring基本使用及源码分析_第8张图片

       点开后发现里面的配置项和属性非常的多,现在先仅对bean的存储和读取进行分析。找到beanFactory,顾名思义,这个就是bean工厂,放在bean的地方,然后点开

[spring学习]2、spring基本使用及源码分析_第9张图片

        然后找到beanDefinitionMap,这个也和名字一样,就是bean的一个映射,点开

[spring学习]2、spring基本使用及源码分析_第10张图片

[spring学习]2、spring基本使用及源码分析_第11张图片

        点开后发现里面有很多属性,最重要的就是table,这个table的类型就是ConcurrentHashMap$Node,用来存储bean的配置信息。默认大小是512,会自动扩容,点开,然后找到配置的people,我这边是109索引

[spring学习]2、spring基本使用及源码分析_第12张图片

         点开,查看里面信息

[spring学习]2、spring基本使用及源码分析_第13张图片

         可以看见,这里面有hash,表示该对象的哈希值,key就是我们配置的id,val就是配置的具体信息,next就是一个指针,着重对val进行查看,下面展示val

[spring学习]2、spring基本使用及源码分析_第14张图片

        找到peopertyValues,点开,然后点击prepertyValueList,可以发现里面有elementData,这给存放我们配置的property属性,size表示有多少个

[spring学习]2、spring基本使用及源码分析_第15张图片

         点开elementData,查看每一项

[spring学习]2、spring基本使用及源码分析_第16张图片

[spring学习]2、spring基本使用及源码分析_第17张图片

         可以发现,我们在xml文件中配置的信息就存放在了这里。


单例对象池

        上面是我们的xml配置项的存放地方,那我们的实例化对象存放在哪里呢?答案就是单例对象池(如果是单例对象且不是懒加载),下面我们去找一下单例对象池。

         在beanFactory下面找到singletonObjects,点开

[spring学习]2、spring基本使用及源码分析_第18张图片

[spring学习]2、spring基本使用及源码分析_第19张图片

         我们由spring创建的对象就存放在table中,可以看见,table的类型是一个ConcurrentHashMap$Node,现在打开table,然后找到我们的people对象。当然除了这个对象还有一些spring预制的对象。

[spring学习]2、spring基本使用及源码分析_第20张图片

[spring学习]2、spring基本使用及源码分析_第21张图片

         可以发现,key就是xml中配置的id,而val的类型是一个People,就是spring帮我们创建的对象,我们通过getBean(id),就是在这个table里面查找是否对应key。

        到这里,我们就把spring执行getBean的流程分析完了。


细节说明

        如果细心的化,我们就可以发现,在beanDefinitionMap中配置项的存储位置和singletonObjects中的存储位置是一样的,都是109索引。

[spring学习]2、spring基本使用及源码分析_第22张图片


不指定id 

       我们在xml文件中给people配置了id,我们就是通过这个id来获取对象,如果不配置id会怎么样呢?答案就是spring会给对象分配一个id,id的名字就是对象全类名#0(1,2....),例如,我们在xml文件中将id删除,然后我们通过debug找到People的存储位置,查看id,id如下

[spring学习]2、spring基本使用及源码分析_第23张图片

         可以发现,spring分配的id就是类的com.ttpfx,spring.bean.People#0,如果还有一个Peolpe也没有分配id,那么spring分配的id就是com.ttpfx.spring.bean.People#1


总结 

        通过这篇文章,我们初次使用了spring,并且也对spring是如何执行getBean进行了分析,对spring的ioc有了个大概认识,在下一篇文章中,将会介绍基于xml的bean配置。

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