Spring源码解析笔记


虽然现在已经普遍在用Springboot了,但是Spring还是得熟悉一下,永远都在用别人的而不知其所以然

1.基本Pom:


    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-beansartifactId>
      <version>${springframework.version}version>
    dependency>
    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-coreartifactId>
      <version>${springframework.version}version>
    dependency>
    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-contextartifactId>
      <version>${springframework.version}version>
    dependency>
    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-expressionartifactId>
      <version>${springframework.version}version>
    dependency>
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-context-supportartifactId>
      <version>${springframework.version}version>
    dependency>

  
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-aopartifactId>
      <version>${springframework.version}version>
    dependency>
  
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-aspectsartifactId>
      <version>${springframework.version}version>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-messagingartifactId>
      <version>${springframework.version}version>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-jdbcartifactId>
      <version>${springframework.version}version>
    dependency>

    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-ormartifactId>
      <version>${springframework.version}version>
    dependency>
    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-jmsartifactId>
      <version>${springframework.version}version>
    dependency>
    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-txartifactId>
      <version>${springframework.version}version>
    dependency>
    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webartifactId>
      <version>${springframework.version}version>
    dependency>
    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-webmvcartifactId>
      <version>${springframework.version}version>
    dependency>
    
    <dependency>
      <groupId>org.springframeworkgroupId>
      <artifactId>spring-websocketartifactId>
      <version>${springframework.version}version>
    dependency>

2.基本使用

·2.1 声明bean的配置  这里我们先使用最基础的XMl配置而不是注解

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="studentBean" class="com.spring.modu1.Student">
        <property name="age" value="1"/>
        <property name="name" value="张三"/>
    bean>
beans>

2.2 基本流程

2.2.1声明实体

public class Student {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

 2.2.2  SpringBean简单加载流程

/**
 * Hello Spring!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        //第一步声明资源加载配置
        Resource resource =new ClassPathResource("BeanRegistry.xml");
        //第二步建立全局工厂
        DefaultListableBeanFactory defaultListableBeanFactory=new DefaultListableBeanFactory();
        //构建资源读取器用来给工厂加载资源
        XmlBeanDefinitionReader beanDefinitionBuilder= new XmlBeanDefinitionReader(defaultListableBeanFactory);
        //加载资源
        beanDefinitionBuilder.loadBeanDefinitions(resource);
        //程序需要实体时直接从工厂拿对应的对象
        Student bean = defaultListableBeanFactory.getBean(Student.class);
        System.out.println(bean.getAge().toString()+"---"+bean.getName().toString());

    }
}

3.Spring加载Bean基本过程说明:

  • 把需要定义的Bean加载在Spring的配置文件中,包括注解或者Xml形式

  • 需要通过Spring相关的Resource来加载对应的配置文件

  • 显示声明一个Spring工厂,该工厂用来掌控我们在配置文件中配置的各种bean以及Bean之间的依赖管理及注入关系

  • 需要定义一个配置信息读取器,该读取器用来读取我们之前配置的各种bean配置文件

  • 读取器的作用是读取我们的配置文件信息,并且将读取的信息装配到我们之前所声明的工厂当中

  • 上一流程中,我们需要将读取器与工厂及资源对象进行相应的关联处理

  • 工厂配置的bean已装载完毕,可以供客户端直接调用获取客户需要的bean

4.逐步分析

4.1 第一步构建资源

4.1.1 Spring的资源在Spring中占据很大的一部分,Resource为资源的顶级接口,Spring通过各类资源的加载进行管理,比我除了我们演示的xml资源,还可以加载各类文件,URl资源登
Resource resource = new ClassPathResource("SpringBeanConfig.xml");

 4.BeanFactoory  所有工厂最顶层的抽象

beanFactory 基本方法不多,其子类或实现根据具体的情景实现

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String var1) throws BeansException;

     T getBean(String var1, Class var2) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

     T getBean(Class var1) throws BeansException;

     T getBean(Class var1, Object... var2) throws BeansException;

    boolean containsBean(String var1);

    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;

    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;

    String[] getAliases(String var1);
}

 5.源码阅读总结:

关于Spring Bean实例注册流程

  • 定义好Spring的配置文件
  • 通过Resources对象将Spring的配置文件进行抽象,抽象成一个具体的的Resource对象 如ClassPathResources
  • 定义好将要使用的Bean工厂(各种BeanFactory)
  • 定义XmlBeanDefinitionReader 对象,并将工厂的抽象方法作为参数传递进去,从而构建好亮着的关联关系
  • 通过XmlBeanDefinitionReder对象来读取之前的所抽象的Resource对象
  • 流程开始解析--
  • 针对XMl文件进行各种元素的属性的解析,这里面,真正的解析是通过BeanDefinitionParserDelegate对象来完成的(委托模式)
  • 通过BeanDefinitionParserDelegate 对象在解析Xml文件时,又用到了模板方法的设计模式(pre process  post流程)
  • 当所有的Bean标签元素都解析完毕后,开始定义一个BeanDefinition对象,该对象是一个非常重要的对象,里面容纳了构建一个Bean相关的所有属性
  • BeanDefinition构建完成后,Spring又会创建一个BeanDefinitionHolder对象来持有BeanDefinition对象,它包含两个内容一个是Bean的名称,一个是BeanDefinition对象
  • 工厂将会将解析出来的Bean信息放入到内部的一个CurrentHashMap中,该map的key是BeanName(唯一的),值是Beandefinition对象
  • 调用Bean的解析完成的触发动作,从而触发相应的监听器方法的执行(
    fireComponentRegistered方法 可选
    )(使用了观察者模式)

相关