一、简介
上一篇文章我们实现了基于注解的简单容器的实现,下面在我们正式的学习Spring源码之前,我们先来看一看Spring源码的类结构。有过源码阅读经验的童鞋应该都知道,Spring的源码跳来跳去,显得很乱,但事实上Spring的源码真的乱吗?
二、Spring源码类结构
首先直接上图,Spring中容器有两种,分别是我们所说的低级容器BeanFactory和高级容器ApplicationContext,首先直接上图。我们来看一下这两个容器的类结构。
在正式的认识这两张类结构图之前,我们先来看看接口,抽象类,实现类三者之间的关系,个人觉得正确的认识这三者之间的关系有助于对于Spring源码的理解。
首先,来看这几个实现类。
class Snake {
public void move(){
System.out.println("爬行");
}
public void eat(){
System.out.println("食肉");
}
public void Poisonous(){
System.out.println("有毒");
}
}
class Rabbit {
public void move(){
System.out.println("跳跃");
}
public void eat(){
System.out.println("食草");
}
}
class Lion {
public void move(){
System.out.println("跳跃");
}
public void eat(){
System.out.println("食肉");
}
}
class Bird {
public void move(){
System.out.println("飞行");
}
public void eat(){
System.out.println("食草");
}
}
class Monkey {
public void move(){
System.out.println("跳跃");
}
public void eat(){
System.out.println("食草");
}
public void copy(){
System.out.println("模仿");
}
}
class Deer {
public void move(){
System.out.println("跳跃");
}
public void eat(){
System.out.println("食草");
}
}
我们创建六个简单的动物实现类,每个类都包含几个方法。
我们该如何改造这几个实现类了?
首先,新建动物接口
public interface Animal {
public void move();
public void eat();
}
然后观察所有的实现类,发现对于eat方法,只分为“食草”和“食肉”两种。
即可以将重复代码抽取到抽象类之中。而对于move方法,因其实现多种多样,暂由各实现类单独实现。
class Snake extends MeatAnimal implements Animal{
@Override
public void move(){
System.out.println("爬行");
}
public void Poisonous(){
System.out.println("有毒");
}
}
class Rabbit extends GrassAnimal implements Animal{
@Override
public void move(){
System.out.println("跳跃");
}
}
class Lion extends MeatAnimal implements Animal{
@Override
public void move(){
System.out.println("跳跃");
}
}
class Bird extends GrassAnimal implements Animal{
@Override
public void move(){
System.out.println("飞行");
}
}
class Monkey extends GrassAnimal implements Animal{
@Override
public void move(){
System.out.println("跳跃");
}
public void copy(){
System.out.println("模仿");
}
}
class Deer extends GrassAnimal implements Animal{
@Override
public void move(){
System.out.println("跳跃");
}
}
而对于Snake类中的Poisonous方法和Monkey 中的copy方法,分别为各自的独特方法,对于此类方法,可以通过实现接口或者实现继承接口来构建。
实现接口
public interface Copy {
void copy();
}
public interface Poisonous {
void Poisonous();
}
class Snake extends MeatAnimal implements Animal,Poisonous{
@Override
public void move(){
System.out.println("爬行");
}
@Override
public void Poisonous(){
System.out.println("有毒");
}
}
class Monkey extends GrassAnimal implements Animal,Copy{
@Override
public void move(){
System.out.println("跳跃");
}
@Override
public void copy(){
System.out.println("模仿");
}
}
实现接口继承
public interface Copy extends Animal{
void copy();
}
public interface Poisonous extends Animal{
void Poisonous();
}
class Snake extends MeatAnimal implements Poisonous{
@Override
public void move(){
System.out.println("爬行");
}
@Override
public void Poisonous(){
System.out.println("有毒");
}
}
class Monkey extends GrassAnimal implements Copy{
@Override
public void move(){
System.out.println("跳跃");
}
@Override
public void copy(){
System.out.println("模仿");
}
}
个人觉得在实际开发中关于接口,抽象类,实现类的关系还是非常值得深入思考的,可能在下也讲解的不是特别清楚,大家可以继续自行研究,下面我们来看看Spring中的类结构关系。
首先看DefaultListableBeanFactory的类结构
最上层的BeanFactory接口下分别有三个二级接口 HierarchicalBeanFactory、 HierarchicalBeanFactory、AutowireCapableBeanFactory,然后由 ConfigurableListableBeanFactory继承所有的二级接口,所以接口ConfigurableListableBeanFactory包含了 BeanFactory 体系目前的所有方法,可以说是BeanFactory接口的集大成者。 DefaultListableBeanFactory实现类实现了ConfigurableListableBeanFactory、接口 BeanDefinitionRegistry,继承了抽象类AbstractAutowireCapableBeanFactory。可以看到DefaultListableBeanFactory自上而下的集成了整个BeanFactory体系的所有的功能。其实仔细看,不难看出,BeanFactory的整个体系从上而下进行了非常细致完整的功能拆分,通过层层继承,实现,接口,抽象类对整个体系的功能进行合理拆分。
Applicationcontext的整个体系同样如此,只是在BeanFactory的基础之上进行了更深一级的功能上的扩展,使得其更为强大。
下一篇文章会基于BeanFactory的整个体系对我们的简单容器进行改造。