今天我们首先学习2个设计模式。工厂设计模式 和 模板设计模式
工厂方法模式: 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类实例化延迟到子类。
上图的图很清晰:业务接口有很多实现类,而工厂接口也有还多实现类。每一个工厂的实现类对应一个业务实现类,来控制他们的实例化过程。 如果业务类新增一个实现类,那么我们只要新增一个工厂实现类即可。而每一个业务实现类只负责自身的功能,对于新增的功能不会影响原有的功能,也不需要修改原有的代码,符合单一职责与开闭原则。还不明白的可以看我的另一篇博客《大话设计模式》——读后感 (5)雷锋依然在人间?——工厂方法模式_chen_yao_kerr的博客-CSDN博客
模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的机构即可重定义该算法的某些特定步骤。
其实,只要有类的继承,就会有模板设计模式。
简单点,就是抽象类中写一些公共逻辑,然后子类继承抽象类并重写方法,定义一些子类特有的逻辑,当我们使用这个子类的时候,公共逻辑调用父类的即可,这就是模板设计模式。
复杂点,抽象类中某个方法,比如A,在A方法中定义了一些逻辑,并且根据不同的逻辑调用B、C、D方法。而B、C、D方法都是需要子类去实现的。子类只需要重写B、C、D方法即可,这就是模板设计模式
今天要说的是mybatis的事务,此时就涉及到了工厂设计模式。
Transaction接口有两个实现类:
1. JdbcTransaction:提供JDBC最基本的commit、close、rollback、getConnection功能
2. ManagedTransaction:只提供getConnection功能,其他功能需要让容器WebLogic、tomcat等去实现
还提供了TransactionFactory接口:获取事务的实例对象
1. JdbcTransactionFactory 负责生成JdbcTransaction对象
2. ManagedTransactionFactory: 负责生成 ManagedTransaction
而在我们配置Mybatis数据源信息的时候,我们会进行事务消息的配置:
此外,在Mybatis的核心类Configuration中,我们在构造方法中把具体的工厂类进行了别名注册。这样,我们只需要根据XML中配置的具体事务策略,就可以找到对应的工厂类,而工厂类负责生产处具体的事务对象,很巧妙
总结:
1. 事务这个模块是使用工厂设计模式进行coding的。Factory负责生成具体的事务。而事务又分为2种,具体使用哪一种事务是通过在xml文件中进行配置确定的。
2. 配置使用具体哪一个事务的这种设计,是典型的策略模式。你配置什么,我就用具体不同的策略。此处的策略是指使用JdbcTransaction,还是ManagedTransaction
说清楚了原理,那么进入源码分析
今天的核心是获取到SqlSession。
1. 首先,就是根据我们在XML中配置的<enviroment>标签,找打<transactionManager>标签并获取到事务管理器的类型。此处是JDBC
然后代码会获取到JdbcTransationFactory对象,由他来生成对应的事务对象。此处对应的事务应该是JdbcTransation。
此时,我们回过头来去看XMLConfigBuilder对象的 environmentsElement 方法中去看看,它是如何根据xml的配置信息去生成工厂对象的
进一步跟进源码,我们可以确认如下信息。
此处,不知道大家有没有发现,这是模板设计模式呢?
2. JDBCTransationFactory工厂类实例化JDBCTransation对象。
3. 生成执行器。 执行器后面详细讲
4. 最后,DefaultSqlSessionFactory new 出来一个 DefaultSqlSession
而DefaultSqlSessionFactory 也是mybatis默认生成的。当我们使用建造者SqlSessionFactoryBuilder建造SqlSessionFactory 对象的时候,其实也是直接new出来它的子类DefaultSqlSessionFactory
这个地方需要详细的分析一下 SqlSession 和 SqlSessionFactory 的架构了。其实又是一计工厂设计模式的运用。
观察一下发现,SqlSessionManager实现了SqlSession接口,也实现了SqlSessionFactory接口,根传统的工厂模式还不太一样。其实,我们可以发现,任何所谓的设计模式都是要符合业务需求的,可以根据业务的变化,设计模式本身也可以发生一些变化。
SqlSessionManager 和 DefaultSqlSession比较
1. SqlSessionManager 既是工厂类,也是SqlSession类,可以自己生产自己。而DefaultSqlSession只是一个SqlSession类。
2. SqlSessionManager 使用到了ThreadLocal,不同线程过来都会优先从ThreadLocal获取,获取不到才会生成新的SqlSession对象;
而DefaultSqlSession是由DefaultSqlSessionFactory创建的,每个线程过来DefaultSqlSessionFactory都会创建一个新的DefaultSqlSession。
从性能上来说,SqlSessionManager 性能更高
现在为止,我们已经接触了好几种设计模式了。光mybatis就使用了好几种组合设计模式了。比如 模板 + 工厂, 动态代理 + 工厂。 而在后面,我们还会接触到 适配器 + 工厂设计模式的组合。