背景
- 本文主要深入探讨了MyBatis源码中采用的设计模式,旨在通过分析这些设计模式的应用实例来指导自己如何在自身的业务开发中有效地运用它们。此外,学习MyBatis源码不仅能提升编程技巧和对设计模式的理解,而且有助于在遇到问题时快速定位和解决,从而增强代码的可维护性和扩展性。
设计模式
单例模式
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。这种模式在需要协调多个部分操作或控制对共享资源的访问时非常有用。
单例设计模式实现上主要有饿汉式、懒汉式、双重检查锁定、静态内部类、枚举类型等等。
源码学习
Mybatis用到单例设计模式主要是有ErrorContext,ErrorContext主要用于记录线程中的错误信息。
ErrorContext源码如下,省略部分不涉及的代码
public class ErrorContext {
private static final ThreadLocal<ErrorContext> LOCAL = ThreadLocal.withInitial(ErrorContext::new);
private ErrorContext() {
}
public static ErrorContext instance() {
return LOCAL.get();
}
}
上诉源码中主要是通过懒汉式创建了单例模式,通过上诉源码我们可以学习到懒汉式单例模式需要注意以下几点:
- 需要将构造方法置为private私有方法,防止外部直接创建对象
- 通过static方法在服务创建时就直接初始化
- final 确保对象不会初始化多次
同时也学习到ThreadLocal的一种默认构造方法,ThreadLocal.withInitial方法,主要是指定缺省值时创建工厂方法,这样就可以不用每次都要先创建再使用。
业务实践
在实际业务中,我们经常使用单例模式来控制对象的创建和全局访问点。其中,双重检查加锁方式是一种常用的实现方式,即在方法内部先判断对象是否为空,再进行加锁操作。这种方式可以有效地避免多次创建实例的问题,同时保证了线程安全。源码如下:
private static volatile LocalCacheManager instance;
public static LocalCacheManager getInstance() {
if (instance == null) {
synchronized (LocalCacheManager.class) {
if (instance == null) {
LocalCacheManager i = new LocalCacheManager();
i.init();
instance = i;
}
}
}
return instance;
}
实际上,对象在很多场景中都会用到,因此我们可以直接通过饿汉模式创建对象。这种方式的代码更简单,即使对一些新手来说也不容易出错。例如,可能会出现未加锁或者未在synchronized中再次判断对象是否为null的情况,包括未使用volatile导致因JVM指令重排导致服务重复创建的问题。
个人思考
- 学习设计模式的过程能够给人带来更深刻的体会,相比于直接查看源码,它能够帮助我们更好地理解源码中使用到的一些方法,并将其补充到个人知识树中。
本文详细解读了MyBatis源码中单例模式的实现,重点讲解了ErrorContext的懒汉式单例模式,并讨论了在实际业务中的应用,如双重检查锁定和不同创建模式的优缺点。
547

被折叠的 条评论
为什么被折叠?



