# litespring
**Repository Path**: zlray/litespring
## Basic Information
- **Project Name**: litespring
- **Description**: litespring
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 2
- **Created**: 2020-11-01
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
改代码位置在:https://github.com/onlyliuxin/litespring
我自己的代码库:https://gitee.com/baishui0212/litespring
(1)手写spring基本的 IOC 和AOP的相关功能点
(2)一个阶段的内容会按照分支的形式进行提交
(3)会把每个阶段的大概内容记录下来的
(4)类图在 【litespring.drawio】 中
======================= 第一个阶段 =============================
【主要内容:BeanFactory,BeanDefinition,Resource,SingletonBeanRegistry】
version-1
实现的功能点:
BeanDefiniton:bean的定义信息 ======》 GenericBeanDefinition
BeanFactory的接口,以及对应的实现类 ======》 DefaultBeanFactory
(1)使用构造器传入配置文件信息
(2)获取对应的classLoader,获取该配置文件的流信息
(3)DOM解析
(4)保存bean的定义信息,只是定义,并没有真正的实例化
getBean()方法
(1)从beanMap中获取bean的定义信息,就是对应的classpath,test.service.BaishuiService
(2)获取当前的classLoader进行bean的实例化
(3)返回bean
不足的地方:DefaultBeanFactory中包含了很多的功能点,比如,读取文件,解析文件,保存bean信息等
经验点:
(1)classUtils 工具类使用abstract,防止被其他程序实例化,目的:工具类静态方法的调用
(2)单一职责原则
version-2
单一职责原则:
职责:是引起变化的原因
- 如果多余一个的动机去改变这个类,这个类就具备多个职责
SRP:对于一个类而言,应该只有一个引起他变化的原因
BeanFactory的拆分
(1)配置文件读取和解析 -> XmlBeanDefinitionReader 和 BeanDefinitionRegistry
引入Application和ClassPathApplicationContext
version-2-1
增加 Resource ClassPathResource FileSystemResource:负责创建出不同的流
Resource 的作用就是持久不同的InputStream
进行loadBeanDefinitions的时候,只需要传入Resource即可
引入FileSystemXmlApplicationContext
version-2-2
模版方法 引入 AbstractApplicationContext,获取不同的Resource
FileSystemXmlApplicationContext 和 ClassPathApplicationContext
version-2-3
增加 ConfigurableBeanFactory :classloader的设置以及获取
version-2-4
处理scope的问题
增加 SingletonBeanRegistry 接口 对应实现:DefaultSingletonBeanRegistry
DefaultBeanFactory作用:
(1)承担 ConfigurableBeanFactory
(2)注册 bean 的定义信息 BeanDefinitionRegistry
(3)生成并保存单例bean的作用
======================= 第二个阶段 =============================
【setter的注入,以及增加了xml文件对setter的描述的类,比如 TODO 】
TDD:BaishuiV2Service,Car,House,litespring-v2.xml
引入 PropertyValue{
private String name;
private Object value:-》 保存的是各种bean的Reference,待后续 TypeConverter 进行解析
private Object convertedValue; -> 实际存放的ref的 实例对象
}
RuntimeBeanReference TypedStringValue
xml中的property的顺序问题
BeanDefinitionValueResolver: 解析PropertyValue中的value中,转换成真正的实例对象,
需要持有BeanFactory中实例
--- 增加了log
拆分了createBean方法:instantiateBean 和 populateBean
先进行实例化,而后进行setter进行注入属性
引入 BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); - JDK
引入类型转换:TypeConverter SimpleTypeConverter PropertyEditor[java]--TODO
======================= 第三个阶段 =============================
【构造函数,增加了】
BeanDefinition中增加了属性【ConstructorArgument】来进行描述
ValueHolder 只在 ConstructorArgument 中使用,高内聚,低耦合
静态内部类:ValueHolder{
name
type
value
}
ConstructorArgument
Collections.unmodifiableList(this.argumentValues) -- 返回不可修改集合
疑问点:
存在多个构造器,使用哪个构造器进行初始化呢???
======================= 第四个阶段 =============================
【实现Spring的注解】
具体步骤:
(1)读取XML文件
(2)对指定的package包进行扫描,标记为 @Component,并转换为 beanDefinition
2.1 把一个package包下面的class变成 Resource
引入 PackageResourceLoader
2.2 使用ASM读取Resource中的注解
2.3 创建BeanDefiniton
(3)通过Beanfinition创建bean的实例,根据注解进行注入
======= ASM ========
- 一个可以操作java字节码的框架
- 可以读取和修改class中的字节码
工作模式:Visitor模式
Class Reader
Class Visitor
Class Writer
======================= 第五个阶段 =============================
如何实现AOP
(1)编译期 “增强”:AspectJ
(2)运行期动态生成类 -> 代理类
CGLib
JDK的动态代理
专业术语:
Joint Point:代表一个方法的执行点
PointCut:匹配joint point的断言 -> 本质就是execution()
Advice:拦截器
Before Advice:
步骤:
(1)PointCut:给定一个类的方法,是否和表达式匹配
PointCut MethodMatcher
-> AspectJExpressionPointCut为具体实现
(2)定位Method
需要通过类的名称("tx")和方法名("start")定位到这个method,然后通过反射进行调用
MethodLocatingFactory
(3)ReflectiveMethodInvocation
目标:拦截器能够以正确的顺序执行
aop aliance
需要完成的功能:
(1)根据bean的名称和方法,获取method对象
(2)给定一个类的方法,判断该方法是否符合pointcut的表达式
(3)实现了Before,AfterReturning,AfterThrowing等Advice
(4)实现了Advice按次序执行
- ReflectiveMethodInvocation
(5)给定一个AOPConfig,使用CGLib生成一个对象的代理
(6)从XML中创建 BeanDefiniton
======================= 第六个阶段 =============================
=================================================================
访问class的时候,我们实现了vistor方法,进行class以及注解中的信息的保存
DefaultBeanFactory{
- classLoader{}
- beanDefinitionMap{
GenericBeanDefiniton {
id
beanClassName
singleton
prototype
scope
beanClass
propertyValues{
name
value
converted
convertedValue
}
constructorArgument{
List
}
isSynthetic
}
SannedGenricBeandefinition {
metadata{
annotationSet
attributeMap
className
isInterFace
isAbstract
isFinal
superClassName
interfaces
api
cv
}
}
}
- beanDefinitionProcessors{
beanPostProcessor{
beanFactory
requiredParameterName
requiredParameterValue
autowireAnnotationTypes
}
}
-singletonObjects{
}
}