Spring设计模式总结
**模版方法模式——**Spring的外接扩展
模板方法模式就是父类定义了骨架(调用哪些方法及顺序),某些特定方法由子类实现。
最大的好处:
- 代码复用
- 减少重复代码
- 除了子类要实现的特定方法,其他方法及方法调用顺序都在父类中预先写好了。
所以父类模板方法中有两类方法:
-
**共同的方法:**所有子类都会用到的代码
-
**不同的方法:**子类要覆盖的方法,分为两种:
- 抽象方法:父类中的是抽象方法,子类必须覆盖
- 钩子方法:父类中是一个空方法,子类继承了默认也是空的
注:为什么叫钩子,子类可以通过这个钩子(方法),控制父类,因为这个钩子实际是父类的方法(空方法)
Spring 中的 jdbcTemplate
、hibernateTemplate
等以 Template 结尾的对数据库操作的类,这些就使用到了模板模式。一般情况下,开发者都是通过使用继承的方式来实现模板模式,但 Spring 并没有使用这种方式,而是使用 Callback 模式与模板方法模式配合,既达到了代码复用的效果,同时又增加了灵活性
具体实现:
import java.sql.SQLException;
public abstract class JdbcTemplate {
public final Object execute(String sql)
{
Connection con = null;
Statement stmt = null;
try {
con = getConnection();
stmt = con.createStatement();
Object retValue = executeWithStatement(stmt, sql);
return retValue;
} catch(SQLException e){
...
}finally{
closeStatement(stmt);
releaseConnection(con);
}
}
protected abstract Object executeWithStatement(Statement stmt, String sql);
}
为什么JdbcTemplate没有使用继承?
因为这个类的方法太多,但是我们还是想用到JdbcTemplate已有的稳定的、公用的数据库连接,那么我们怎么办呢?
我们可以把变化的东西抽出来作为一个参数传入JdbcTemplate的方法中。但是变化的东西是一段代码,而且这段代码会用到JdbcTemplate中的变量。怎么办?
那我们就用回调对象吧。在这个回调对象中定义一个操纵JdbcTemplate中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到JdbcTemplate,从而完成了调用。
**责任链模式——**Aop的方法调用
责任链模式:
- 统一的业务接口
- 责任链相当于一个负责人集合,每一个负责人都实现了自己的invoke()方法来处理传进来的数据或对象或对象的指定方法
- 通知下一个负责人处理业务
实现方式:
- 方法1:
- 设计一个责任链执行器,包含责任链集合。责任链执行器中有一个proceed(),方法内遍历执行负责人的invoke()方法,invoke方法以执行器作为参数
- invoke(执行器)处理完业务后,执行器又调用proceed()方法,将索引移到下一个负责人位置。
这样:执行器和负责人的方法相互调用,而执行器通过移动索引通知下一个负责人处理业务。
- 方法2:
- 基于链表的责任链,每一个负责人是一个责任节点Node,包含指向下一个负责人的next引用
- 负责人的处理业务的方法 invoke()这时不带参数,invoke()方法里面递归调用invoke()方法,并设置出口条件。出口条件可以是next!=null
在Spring中的应用
CglibAopProxy类
new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
参数 chain:拦截器链,保含了目标方法的所有切面方法 ,从chain里面的数组元素的顺序来看,拦截器的顺序before不再after前面执行。
每一个 Interceptor有一个**invoke()**方法
Interceptor是一个空接口 MethodInterceptor extends Interceptor
Spring的拦截器 xxxInterceptor都实现了自己的 Object invoke(MethodInvocation invocation)方法
其中ReflectiveMethodInvocation implements ProxyMethodInvocation ,ProxyMethodInvocation extends MethodInvocation,ReflectiveMethodInvocation类中的 proceed()方法会遍历拦截器链,调用每个拦截器的invoke方法,传入ReflectiveMethodInvocation自身作为参数,
每个拦截器的invoke方法做两件事(这两件事的执行顺序因拦截器的功能而异)
- 执行自己的业务逻辑
- 执行ReflectiveMethodInvocation的proceed()
这样就实现了链式调用