Skip to content

AdamZHC/simple_spring

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@Hand Written Spring

IOC

本质上就是容器管理对象的获取,Map用来做实际的管理

难点

Spring本质上利用了一系列设计模式,可以说把设计模式运用的十分灵活,同样把面向对象的思想也运用地炉火纯青

拆分BeanDefinitionBeanSingetonRegistry

初期阅读没有搞懂,后来意识到就是把extendsimplements的思路组合到一起,本质上是在一个地方将这个合了起来,但是工厂类的实现需要借助与单例注册表的实现,方便模块的聚合拆分

另外,对于一些特殊的接口继承的思想,或者说核心方法的抽象也很重要

核心方法接口

​ 简单做个说明,核心方法的实现通过接口来封装,本质上是为了抽象最终的方法,下面三个接口都是极为重要的,实现了获取bean,注册beandefinition的重要方法

  • BeanFactory
  • SingletonBeanRegistry
  • BeanDefinitionRegistry

抽象类的理解

这里的实现就是介于interfaceclass中间的类,这里有一个神操作就是,可以把类的实现分阶段进行,也就是可以在没有实现的时候就调用这个类,因为最终可以保证所有的方法都是被实现过的,因此这样的操作是允许实现的,但是看起来有又特别有操作

加载流程

过程就是先注册,后获得对应的实例类,因此这里的核心是有一个BeanDefinitionRegistry注册表和BeanSingletonObjectRegistry注册表,也就是说,我们需要先去注册到这个注册表里面,然后等加载的时候实现懒加载

懒加载

通过反射的思路实现懒加载

@流程简述

首先有若干的原则:

  • 模块拆分:factroysingleton
  • 供用户调用的方法使用接口来实现
  • 尽量在核心实现类里面存放对应的属性值

首先是调用registerBeanDefinition方法,实现对于BeanDefinition的注册,然后调用getBean方法的时候,在BeanDefiniationRegistry获得类的Class类,之后在SingletonObjectRegistry类中获取对应的Object对象,如果没有的话就是直接getBeanDefinitionaddSingletonObject两个操作

实现加载实例对象的有参构造

关键在于这个反射方法的使用,以及这个Constructor的使用,就是对应的这个类的方法,可以通过Class以及构造方法的特点(参数个数等),获取Constructor对象,并且根据这个Constructor对象传参获取对应的实例对象,而实现的其中关键一点就是在此,另外就是实例模块的拆分 和之前一样就是一个接口,然后实现类,最终作为成员变量使用

实现对象的属性构造

注意这里没有分清楚,对象的属性指的是getter and setter实例成员变量,和一般地在constructor分配的变量不是一样的,因此**Bean其实就是,有getter and setter方法的对象,代指现实世界中的事物,所以说可以允许constructor中没有对应的属性,但是要在成员方法里面有getter and setter方法,同时还有对应的引用**属性,也就是说有抽象数据类型,不单单是int string long char等等

实现的思路还是模块化地设计,实现的难度并不高

关键就是有一个Property的思想,然后可以实现对应的操作,加进去之后,在createBean之后,通过BeanDefinitionProperties完成属性的填充,这里的意思就是说,在注册的时候就已经实现了Property的若干实现了,但是针对于真正的实例化的情况,是在getBean完成的,会根据BeanDefinition里面的值来完成对应的bean的设计

实现Xml的配置资源实例化

这一部分的实现很清晰,并不是很难,吐槽一下因为这一章的源码多了很多其它架构的代码,和本身的实现没有关系,加上之后我就看不懂了,因此是感觉有点恶心,其实弄清楚这一点之后,后面的实现是很简单的,Xml的实现分为两部分,第一部分就是资源的抽象化Resource抽象的实现,其实也就是一个核心接口,然后实现不同的资源,另外ResourceLoader的实现是根据方法的参数返回值实现的,并不是通过直接加成员变量实现的,这一点是不太一样的,另一部分的实现就是通过经典的三个接口类继承的思路interface abstract class class来实现功能的添加,本质的实现也是很简单的,并没有很复杂。

实现Application

本质上的设计流程和之前是一样的,基本上没有啥区别,就是三个接口类的继承关系,然后主要注意流程的流转使用

另外这个功能是对于BeanFactory的功能进行一个封装,并不是在BeanFactory里面添加功能

实现PostProcessor

这一部分有点复杂,这里的本质上还是对BeanFactory进行功能扩展,也就是把核心功能放到一个接口,然后在后面实现继承实现的功能,也就是把这个部分功能加到一块去,注意每个功能扩展的实现,都是通过加一些接口,实现类,然后通过继承或者依赖的关系来调用

AOP

代理模式

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。

注解

jdk注解

@Override :用来标识重写方法 @Deprecated标记就表明这个方法已经过时了,但我就要用,别提示我过期 @SuppressWarnings(“deprecation”) 忽略警告 @SafeVarargs jdk1.7出现,堆污染,不常用 @FunctionallInterface jdk1.8出现,配合函数式编程lambda表达式,不常用

元注解——描述注解的注解

@Target 注解用在哪里:类上、方法上、属性上等等 @Retention 注解的生命周期:源文件中、字节码文件中、运行中 @Inherited 允许子注解继承 @Documented 生成javadoc时会包含注解,不常用 @Repeatable注解为可重复类型注解,可以在同一个地方多次使用,不常用

自定义注解

可以规定具体的

反思

应当有的思想是,对于一个功能的相同实现方式,其实就可以开放相同接口就可以,我这里的实现是把JdkCglib分别解耦,其实也可以不用这么做,直接getProxy然后下面两个实现类,或者是作为参数传入,因为功能性的类不需要解耦,所以说可能也用不着这样来实现,但是这样也是一种练习解耦的过程,下次有经验,直接实现功能性的接口,或者作为参数传入即可

待解决的问题

目前有定义有两个接口,在jdkcglib的实现方式解耦过程中都实现了,但是实现的方式是完全一样,但是问题是无法抽离,因此依靠一个实例变量,没法用接口抽象,用父类的话,因为java是单继承也没有办法实现

About

Hand-Written Spring, implementing IOC and AOP

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages