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