设计模式和Spring的源码是每个java程序员都会研究的两个主题。在这里我抛砖引玉,和大家一起探讨下Springboot源码中的设计模式。
让我们从耳熟能详的単例模式开始。大家都知道我们常用的MVC框架中,由Springboot产生的业务bean都是単例的,那Springboot框架是怎么实现的呢?
我们从一个简单的controller开始,
通过@RestController注解我们知道它是由Springboot管理的,ClassPathBeanDefinitionScanner会去扫描类路径下标注了特定注解的类,然后把它们注册到给定的类工厂或者程序上下文中。
启动程序的时候,给定的类工厂是DefaultListableBeanFactory,调用这个类中的preInstantiateSingletons()方法。
我们的主角出现了,继续看它是怎么被创建的,getMergedLocalBeanDefinition()返回了一个RootBeanDefinition的实例,在这实例中定义了要创建的Controller实例是不是単例的。在getMergedLocalBeanDefinition()方法中调用了父类AbstractBeanFactory的getMergedBeanDefinition()方法,在个方法里有这样一段代码
在没有定义范围的时候,设定了BeanDefinition的实例scope属性为singleton。
然后在preInstantiateSingletons()方法中调getBean()去获取name为swadeController的bean,getBean()方法调父类AbstractBeanFactory的doGetBean()方法,在doGetBean()方法中
如果它是単例的就去创建实例,首先在AbstractBeanDefinition的getBeanClass()中获取了类的class
再通过类加载器获取他的默认构造方法,然后创建实例返回。至此我们就得到了SwadeContoller的単例。
单例模式在Springboot的中实现过程是比较复杂的,总结一下就是在Springboot管理了注册在它上下文中的bean,在BeanDifinition中定义了类创建的范围,单例模式的scope就是Singleton。
単例模式实现了,那Springboot为什么要用単例模式来创建我们的业务层实例呢?
1.在程序中这些类是被频繁使用的,让它们保持在内存中,避免了频繁创建、销毁的性能损耗(当然除了业务类,日志类,配置类等都是单例的)。
2.内存中只有一个实例,这样请求过来就会快速的找到有且仅有的一个,节省内存、避免对资源的多重占用和便于管理。
以上是我对Springboot单例模式的见解。欢迎大家在评论里留下自己的见解,让我们一起讨论,一起进步。