写点什么

Spring 中使用的设计模式,mybatis 自动映射原理

作者:Java高工P7
  • 2021 年 11 月 10 日
  • 本文字数:3585 字

    阅读完需:约 12 分钟

  1. 执行 sql 语句,

  2. 关闭资源),


在这些步骤中第 3 步和第四步是不确定的,所以就留给客户实现,而我们实际使用 JdbcTemplate 的时候也确实是只需要构建 SQL 就可以了.这就是典型的模板模式。我们以 query 方法为例来看下 JdbcTemplate 中的代码


// 在 execute 方法中定义好了 jdbc 操作的流程


// action.doInStatement(stmtToUse);是回调方法也就是钩子


@Override


public <T> T execute(StatementCallback<T> action) throws DataAccessException {


Assert.notNull(action, "Callback object must not be null");


Connection con = DataSourceUtils.getConnection(getDataSource());


Statement stmt = null;


try {


Connection conToUse = con;


if (this.nativeJdbcExtractor != null &&


this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {


conToUse = this.nativeJdbcExtractor.getNativeConnection(con);


}


stmt = conToUse.createStatement();


applyStatementSettings(stmt);


Statement stmtToUse = stmt;


if (this.nativeJdbcExtractor != null) {


stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);


}


T result = action.doInStatement(stmtToUse);


handleWarnings(stmt);


return result;


}


catch (SQLException ex) {


// Release Connection early, to avoid potential connection pool deadlock


// in the case when the exception translator hasn't been initialized yet.


JdbcUtils.closeStatement(stmt);


stmt = null;


DataSourceUtils.releaseConnection(con, getDataSource());


con = null;


throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);


}


finally {


JdbcUtils.closeStatement(stmt);


DataSourceUtils.releaseConnection(con, getDataSource());


}


}


query 方法


@Override


public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {


Assert.notNull(sql, "SQL must not be null");


Assert.notNull(rse, "ResultSetExtractor must not be null");


if (logger.isDebugEnabled()) {


logger.debug("Executing SQL query [" + sql + "]");


}


// 实现模板中预留的功能


class QueryStatementCallback implements StatementCallback<T>, SqlProvider {


@Override


public T doInStatement(Statement stmt) throws SQLException {


ResultSet rs = null;


try {


// 此处具体执行查询操作


rs = stmt.executeQuery(sql);


ResultSet rsToUse = rs;


if (nativeJdbcExtractor != null) {


rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);


}


// 处理数据封装操作


return rse.extractData(rsToUse);


}


finally {


JdbcUtils.closeResultSet(rs);


}


}


@Override


public String getSql() {


return sql;


}


}


return execute(new QueryStatementCallback());


}


4.观察者模式




观察者模式定义的是对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。使用比较场景是在监听器中而 spring 中 Observer 模式常用的地方也是 listener 的实现。如 ApplicationListener。 Spring 中的事件监听请参考我的另一篇文章


Spring之事件监听(观察者模型)


5.工厂模式



简单工厂模式

简单工厂模式就是通过工厂根据传递进来的参数决定产生哪个对象。Spring 中我们通过 getBean 方法获取对象的时候根据 id 或者 name 获取就是简单工厂模式了。


<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"


xmlns:context="http://www.springframework.org/schema/context"


xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">


context:annotation-config/


<bean class="com.dpb.pojo.User" id="user" >


<property name="name" value="波波烤鸭"></property>


</bean>


</beans>

工厂方法模式

在 Spring 中我们一般是将 Bean 的实例化直接交给容器去管理的,实现了使用和创建的分离,这时容器直接管理对象,还有种情况是,bean 的创建过程我们交给一个工厂去实现,而 Spring 容器管理这个工厂。这个就是我们讲的工厂模式,在 Spring 中有两种实现一种是静态工厂方法模式,一种是动态工厂方法模式。以静态工厂来演示


/**


  • User 工厂类

  • @author dpb[波波烤鸭]


*/


public class UserFactory {


/**


  • 必须是 static 方法

  • @return


*/


public static UserBean getInstance(){


return new UserBean();


}


}


application.xml 文件中注册


<beans xmlns="http://www.springframework.org/schema/beans"


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"


xsi:schemaLocation="http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans.xsd">


<bean class="com.dpb.factory.UserFactory" factory-method="getInstance" id="user2"/>


</beans>



6.适配器模式




将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。这就是适配器模式。在 Spring 中在 AOP 实现中的 Advice 和 interceptor 之间的转换就是通过适配器模式实现的。


class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {


@Override


public boolean supportsAdvice(Advice advice) {


return (advice instanceof MethodBeforeAdvice);


}


@Override


public MethodInterceptor getInterceptor(Advisor advisor) {


MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();


// 通知类型匹配对应的拦截器


return new MethodBeforeAdviceInterceptor(advice);


}


}


详细介绍可以参考此文Spring之AOP适配器模式


7.装饰者模式




装饰者模式又称为包装模式(Wrapper),作用是用来动态的为一个对象增加新的功能。装饰模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。


spring 中用到的包装器模式在类名上有两种表现:一种是类名中含有 Wrapper,另一种是类名中含有 Decorator。基本上都是动态地给一个对象添加一些额外的职责。


具体的使用在 Spring session 框架中的 SessionRepositoryRequestWrappe


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


r 使用包装模式对原生的 request 的功能进行增强,可以将 session 中的数据和分布式数据库进行同步,这样即使当前 tomcat 崩溃,session 中的数据也不会丢失。


查看需要的 maven 依赖


<dependency>


<groupId>org.springframework.session</groupId>


<artifactId>spring-session</artifactId>


<version>1.3.1.RELEASE</version>


</dependency>


8.代理模式




代理模式应该是大家非常熟悉的设计模式了,在 Spring 中 AOP 的实现中代理模式使用的很彻底,如果不了解代理模式欢迎查看我之前的文章,链接在顶部。


9.策略模式




策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法。并且由客户端决定调用哪个算法,spring 中在实例化对象的时候用到 Strategy 模式。


@Override


public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {


// Don't override the class with CGLIB if no overrides.


if (bd.getMethodOverrides().isEmpty()) {


Constructor<?> constructorToUse;


synchronized (bd.constructorArgumentLock) {


constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;


if (constructorToUse == null) {


final Class<?> clazz = bd.getBeanClass();


if (clazz.isInterface()) {


throw new BeanInstantiationException(clazz, "Specified class is an interface");


}


try {


if (System.getSecurityManager() != null) {


constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {


@Override


public Constructor<?> run() throws Exception {


return clazz.getDeclaredConstructor((Class[]) null);


}


});


}


else {


constructorToUse = clazz.getDeclaredConstructor((Class[]) null);


}


bd.resolvedConstructorOrFactoryMethod = constructorToUse;


}


catch (Throwable ex) {


throw new BeanInstantiationException(clazz, "No default constructor found", ex);


}


}


}


return BeanUtils.instantiateClass(constructorToUse);


}


else {


// Must generate CGLIB subclass.


return instantiateWithMethodInjection(bd, beanName, owner);}

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
Spring中使用的设计模式,mybatis自动映射原理