目录
1 struts2的设计模式
1.1 MVC模式(复合模式)
M-模型(Javabean)-观察者模式
V-视图(JSP)-组合模式
C-控制器(servlet)-策略模式
1.2 command命令模式
action的整个调用过程
命令模式的结构:
(1)Command 抽象命令类
(2)ConcreteCommand 具体命令类
(3)Invoker 调用者/请求者:请求的发送者,它通过命令对象来执行一个请求。一个调用者并不需要再设计的时候确定其接收者,因此它只与抽象命令之间存在关联。在程序运行时,将调用命令对象的execute(),间接调用接收者的相关操作。
(4)Receiver 接收者:接收者执行与请求相关的操作,具体实现对请求的业务处理。
1.3 proxy代理模式
struts2的拦截器体系是一种AOP设计哲学,而通过一个Dynamic Proxy对所有需要管理的action进行加
载,并根据配置,在invoke方法中对当前调用的方法名进行判定,并为其加上合适的事务管理代码。即通过
Method.invoke方法调用被代理类的原始方法实现,这样我们就可以在被代理类的方法调用前后做一些处理。
1.4 单例模式
struts2的servlet默认是多例的,即每次请求都会实例化一个action对象,当然如果是并发多线程的话也是线程安全的。但是,如果struts2交给spring来事务管理的话,则会默认变成单例模式(但是如果是并发多线程的话则是线程不安全),当然也可以在spring的action bean配置的时候设置scope=“prototype”,令其变为多例。
1.5 adatper适配器模式
struts2的action中即有继承又有实现多个接口,即适配多个接口。
extends ActionSupport implements ServletRequestAware, ServletResponseAware
1.6 责任链模式
Struts2中,其拦截器结构的设计,是一个典型的责任链模式的应用。首先将整个执行划分成若干相同类型的元素,每个元素具备不同的逻辑责任,并将他们纳入到一个链式的数据结构中(我们可以把堆栈结构也看作是一个递归的链式结构),而每个元素又有责任负责链式结构中下一个元素的执行调用。
这样的设计,从代码重构的角度来看,实际上是将一个复杂的系统,分而治之,从而使得每个部分的逻辑能够高度重用并具备高度可扩展性。所以,Interceptor结构实在是Struts2/Xwork设计中的精华之笔。
Struts2拦截器执行机理如下:
(1) 整个结构就如同一个堆栈,除了Action以外,堆栈中的其他元素是Interceptor
(2)Action位于堆栈的底部。由于堆栈"先进后出"的特性,如果我们试图把Action拿出来执行,我们必须首先把位于Action上端的Interceptor拿出来执行。这样,整个执行就形成了一个递归调用
(3)每个位于堆栈中的Interceptor,除了需要完成它自身的逻辑,还需要完成一个特殊的执行职责。这个执行职责有3种选择:
- 中止整个执行,直接返回一个字符串作为resultCode
- 通过递归调用负责调用堆栈中下一个Interceptor的执行
- 如果在堆栈内已经不存在任何的Interceptor,调用Action
2 spring mvc的设计模式
MVC模式(复合模式)、代理模式、工厂模式、适配器模式、单例模式和策略模式。
3 spring的设计模式
3.1 工厂模式
spring有很多地方都用到了工厂模式,这里就举一个例子,Spring中非常重要的一个类AbstractFactoryBean。
// AbstractFactoryBean.java
// 继承了FactoryBean,工厂Bean的主要作用是为了实现getObject()返回Bean实例
public abstract class AbstractFactoryBean<T> implements FactoryBean<T>, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
// 定义了获取对象的前置判断工作,创建对象的工作则交给了一个抽象方法
// 这里判断了Bean是不是单例并且是否已经被加载过了(未初始化但加载过了,这个问题涉及到Spring处理循环依赖,以后会讨论到)
public final T getObject() throws Exception {
return this.isSingleton()?(this.initialized?this.singletonInstance:this.getEarlySingletonInstance()):this.createInstance();
}
// 由子类负责具体创建对象
protected abstract T createInstance() throws Exception;
}
之所以这么写是因为这种写法带来了两个好处:
(1) 保证了创建Bean的方式的多样性
Bean工厂有很多种,它们负责创建各种各样不同的Bean,比如Map类型的Bean,List类型的Bean,Web服务Bean,子类们不需要关心单例或非单例情况下是否需要额外操作,只需要关心如何创建Bean,并且创建出来的Bean是多种多样的。
(2) 严格规定了Bean创建前后的其它动作
虽然子类可以自由的去创建Bean,但是创建Bean之前的准备工作以及创建Bean之后对Bean的处理工作是AbstractFactoryBean设定好了的,子类不需要关心,也没权力关心,在这个例子中父类只负责一些前置判断工作。
工厂方法模式非常的有趣,它给了子类创建实例的自由,又严格的规定了实例创建前后的业务流程。
3.2 单例模式
spring管理的bean默认单例模式(但是如果是并发多线程的话,有成员变量则是线程不安全),当然也可以在spring的bean配置的时候设置scope=“prototype”,令其变为多例。
3.3 适配器模式
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类
可以一起工作。
在Spring的Aop中,使用的Advice(通知)来增强被代理类的功能。Spring实现这一AOP功能的原理就使用代理模
式(1、JDK动态代理。2、CGLib字节码生成技术代理。)对类进行方法级别的切面增强,即,生成被代理类的代
理类, 并在代理类的方法前,设置拦截器,通过执行拦截器重的内容增强了代理方法的功能,实现的面向切面编
程。
Advice(通知)的类型有:BeforeAdvice、AfterReturningAdvice、ThreowSadvice的。
在每个类型Advice(通知)都有对应的拦截器:
MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor。
Spring需要将每个Advice(通知)都封装成对应的拦截器类型,返回给容器,所以需要使用适配器模式对Advice进
行转换。
3.4 代理模式
在Spring的Aop中,使用的Advice(通知)来增强被代理类的功能。Spring实现这一AOP功能的原理就使用代理模
式(1、JDK动态代理。2、CGLib字节码生成技术代理。)对类进行方法级别的切面增强,即,生成被代理类的代
理类, 并在代理类的方法前,设置拦截器,通过执行拦截器重的内容增强了代理方法的功能,实现的面向切面编
程。
3.5 装饰者模式
动态的给一个对象添加一些额外的职责。
Spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。
3.6 观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
Spring中Observer模式常用的地方是listener的实现。如ApplicationListener。
3.7 策略模式
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
Spring中在实例化对象的时候用到Strategy模式,即将相应的对象依赖注入到相应的对象中。
3.8 模板方法模式
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
spring的JdbcTemplate就用到了很多模板方法,当然spring ioc容器初始化时,也用到了模板方法。