本质上就是容器管理对象的获取,Map
用来做实际的管理
Spring
本质上利用了一系列设计模式,可以说把设计模式运用的十分灵活,同样把面向对象的思想也运用地炉火纯青
初期阅读没有搞懂,后来意识到就是把extends
和implements
的思路组合到一起,本质上是在一个地方将这个合了起来,但是工厂类的实现需要借助与单例注册表的实现,方便模块的聚合拆分
另外,对于一些特殊的接口继承的思想,或者说核心方法的抽象也很重要
简单做个说明,核心方法的实现通过接口来封装,本质上是为了抽象最终的方法,下面三个接口都是极为重要的,实现了获取bean
,注册beandefinition
的重要方法
BeanFactory
SingletonBeanRegistry
BeanDefinitionRegistry
这里的实现就是介于interface
和class
中间的类,这里有一个神操作就是,可以把类的实现分阶段进行,也就是可以在没有实现的时候就调用这个类,因为最终可以保证所有的方法都是被实现过的,因此这样的操作是允许实现的,但是看起来有又特别有操作
过程就是先注册,后获得对应的实例类,因此这里的核心是有一个BeanDefinitionRegistry
注册表和BeanSingletonObjectRegistry
注册表,也就是说,我们需要先去注册到这个注册表里面,然后等加载的时候实现懒加载
通过反射的思路实现懒加载
首先有若干的原则:
- 模块拆分:
factroy
和singleton
- 供用户调用的方法使用接口来实现
- 尽量在核心实现类里面存放对应的属性值
首先是调用registerBeanDefinition
方法,实现对于BeanDefinition
的注册,然后调用getBean
方法的时候,在BeanDefiniationRegistry
获得类的Class
类,之后在SingletonObjectRegistry
类中获取对应的Object
对象,如果没有的话就是直接getBeanDefinition
和addSingletonObject
两个操作
关键在于这个反射方法的使用,以及这个Constructor
的使用,就是对应的这个类的方法,可以通过Class
以及构造方法的特点(参数个数等),获取Constructor
对象,并且根据这个Constructor
对象传参获取对应的实例对象,而实现的其中关键一点就是在此,另外就是实例模块的拆分 和之前一样就是一个接口,然后实现类,最终作为成员变量使用
注意这里没有分清楚,对象的属性指的是getter and setter
的实例成员变量,和一般地在constructor
分配的变量不是一样的,因此**Bean
其实就是,有getter and setter
方法的对象,代指现实世界中的事物,所以说可以允许constructor
中没有对应的属性,但是要在成员方法里面有getter and setter
方法,同时还有对应的引用**属性,也就是说有抽象数据类型,不单单是int string long char
等等
实现的思路还是模块化地设计,实现的难度并不高
关键就是有一个Property
的思想,然后可以实现对应的操作,加进去之后,在createBean
之后,通过BeanDefinition
的Properties
完成属性的填充,这里的意思就是说,在注册的时候就已经实现了Property
的若干实现了,但是针对于真正的实例化的情况,是在getBean
完成的,会根据BeanDefinition
里面的值来完成对应的bean
的设计
这一部分的实现很清晰,并不是很难,吐槽一下因为这一章的源码多了很多其它架构的代码,和本身的实现没有关系,加上之后我就看不懂了,因此是感觉有点恶心,其实弄清楚这一点之后,后面的实现是很简单的,Xml
的实现分为两部分,第一部分就是资源的抽象化Resource
抽象的实现,其实也就是一个核心接口,然后实现不同的资源,另外ResourceLoader
的实现是根据方法的参数返回值实现的,并不是通过直接加成员变量实现的,这一点是不太一样的,另一部分的实现就是通过经典的三个接口类继承的思路interface abstract class class
来实现功能的添加,本质的实现也是很简单的,并没有很复杂。
本质上的设计流程和之前是一样的,基本上没有啥区别,就是三个接口类的继承关系,然后主要注意流程的流转使用
另外这个功能是对于BeanFactory
的功能进行一个封装,并不是在BeanFactory
里面添加功能
这一部分有点复杂,这里的本质上还是对BeanFactory
进行功能扩展,也就是把核心功能放到一个接口,然后在后面实现继承实现的功能,也就是把这个部分功能加到一块去,注意每个功能扩展的实现,都是通过加一些接口,实现类,然后通过继承或者依赖的关系来调用
代理模式是常用的java
设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。简单的说就是,我们在访问实际对象时,是通过代理对象来访问的,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。
@Override
:用来标识重写方法
@Deprecated
标记就表明这个方法已经过时了,但我就要用,别提示我过期
@SuppressWarnings(“deprecation”)
忽略警告
@SafeVarargs jdk1.7
出现,堆污染,不常用
@FunctionallInterface jdk1.8
出现,配合函数式编程lambda
表达式,不常用
@Target
注解用在哪里:类上、方法上、属性上等等
@Retention
注解的生命周期:源文件中、字节码文件中、运行中
@Inherited
允许子注解继承
@Documented
生成javadoc
时会包含注解,不常用
@Repeatable
注解为可重复类型注解,可以在同一个地方多次使用,不常用
可以规定具体的
应当有的思想是,对于一个功能的相同实现方式,其实就可以开放相同接口就可以,我这里的实现是把Jdk
和Cglib
分别解耦,其实也可以不用这么做,直接getProxy
然后下面两个实现类,或者是作为参数传入,因为功能性的类不需要解耦,所以说可能也用不着这样来实现,但是这样也是一种练习解耦的过程,下次有经验,直接实现功能性的接口,或者作为参数传入即可
目前有定义有两个接口,在jdk
和cglib
的实现方式解耦过程中都实现了,但是实现的方式是完全一样,但是问题是无法抽离,因此依靠一个实例变量,没法用接口抽象,用父类的话,因为java
是单继承也没有办法实现