Spring源码解析笔记

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

1.基本Pom:

<!--Spring四大核心-->
    <!--Bean管理-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!--DI IOC-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!-- 全局的对象访问方式-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!--各类表达式 便捷操作-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${springframework.version}</version>
    </dependency>
<!--扩展组件-->
  <!--aop-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${springframework.version}</version>
    </dependency>
  <!--aspect aop的经典应用-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${springframework.version}</version>
    </dependency>
<!--消息传递处理-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-messaging</artifactId>
      <version>${springframework.version}</version>
    </dependency>
<!--消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析。-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${springframework.version}</version>
    </dependency>
<!--对象关系映射提供集成层 包括JPA和Hibernate 使用Spring-orm模块可以将这些O/R映射框架与Spring提供的所有其他功能结合使用,例如声明式事务管理功能。-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!--Java消息传递服务,包含用于生产和使用消息的功能-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jms</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!--普通pojo管理和声明式事务管理-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!--基本的Web开发集成功能,例如多文件上传功能、使用Servlet监听器初始化一个IOC容器以及Web应用上下文。-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!--Spring MVC框架提供了领域模型代码和Web表单之间的清晰分离-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${springframework.version}</version>
    </dependency>
    <!--提供了WebSocket和SocketJS的实现。-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
      <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> T getBean(String var1, Class<T> var2) throws BeansException;

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

    <T> T getBean(Class<T> var1) throws BeansException;

    <T> T getBean(Class<T> 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方法 可选
    )(使用了观察者模式)

 

posted @ 2020-10-22 08:41  胡小华  阅读(108)  评论(0编辑  收藏  举报