spring中用到了哪些设计模式?
第一种、简单工厂模式 (factory)
又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。
spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。如下配置,就是在
HelloItxxz 类中创建一个 itxxzBean。
<beans>
<bean id="singletonBean"
class="com.itxxz.HelloItxxz">
<constructor-arg>
<value>Hello!
这是singletonBean!value>
</constructor-arg>
</
bean>
<bean id="itxxzBean"
class="com.itxxz.HelloItxxz"
singleton="false">
<constructor-arg>
<value>Hello! 这是itxxzBean!
value>
</constructor-arg>
</bean>
</beans>
第二种:单例模式(Singleton)
当我们试图从Spring容器中取得某个类的实例时,默认情况下,Spring会才用单例模式进行创建。
如果我不想使用默认的单例模式,每次请求我都希望获得一个新的对象怎么办呢?很简单,将scope属性值设置为prototype(原型)就可以了
<bean
id="date" class="java.util.Date"
scope="prototype"/>
通过以上配置信息,Spring就会每次给客户端返回一个新的对象实例。
那么Spring对单例的底层实现,到底是饿汉式单例还是懒汉式单例呢?
Spring框架对单例的支持是采用单例注册表的方式进行实现的
第三种:代理模式(proxy)
aop中使用最多,aop基于jdk动态代理和cglib动态代理实现
第四种:适配器模式(Adapter)
原理:适配器相当于一个转接口。将一个类的接口转换为客户希望的另一个接口,Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作。
spring中以adapter结尾的类都是适配器。
DispatcherServlet.class类中doDispatch()中适配器的使用:
//---------------start-------------------------
HandlerExecutionChain mappedHandler =
null;
mappedHandler = this.getHandler(processedRequest);
HandlerAdapter ha =
this.getHandlerAdapter(mappedHandler.getHandler()); //mappedHandler.getHandler()表示获取
controller对象
ModelAndView mv = null;
mv =
ha.handle(processedRequest, response, mappedHandler.getHandler()); //执行controller,返回ModelAndView对象
this.applyDefaultViewName(processedRequest, mv);
//给mv设置返回的视图名称,此方法中包含:mv.setViewName
(this.getDefaultViewName(request));其中此方法中又包含return this.prefix + this.transformPath(lookupPath) + this.suffix;
mappedHandler.applyPostHandle(processedRequest, response, mv);//渲染视图
//---------------end-------------------------
第五种:装饰模式(Decorator)/包装器模式(Wrapper)
原理:装饰对象包含原本对象和装饰物对象;装饰对象含有原本对象的引用
spring中用到的装饰模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。
第六种:观察者(Observer)
原理:一对多的关系,把多个订阅者称之为观察者,把要发送给观察者的内容称为目标
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
spring中Observer模式常用的地方是listener的实现。如ApplicationListener。
第七种:策略模式(Strategy)
即多个if-else,有多个条件进行区分
spring中在实例化对象的时候用到Strategy模式
在SimpleInstantiationStrategy中有如下代码说明了策略模式的使用情况:
第八种:模板方法(Template Method)
原理:实现一个算法时,整体步骤很固定,但是某些部分容易改变,易变得部分可以抽象出来,供子类实现。
spring中的运用:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template
Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
Template
Method模式一般是需要继承的。这里想要探讨另一种对Template
Method的理解。spring中的JdbcTemplate,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用到JdbcTemplate已有的稳定的、公用的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出来作为一个参数传入JdbcTemplate的方法中。但是变化的东西是一段代码,而且这段代码会用到JdbcTemplate中的变量。怎么办?那我们就用回调对象吧。在这个回调对象中定义一个操纵JdbcTemplate中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到JdbcTemplate,从而完成了调用。这可能是Template
Method不需要继承的另一种实现方式吧。
以下是一个具体的例子:
JdbcTemplate中的execute方法
JdbcTemplate执行execute方法 :
所以这里面:createConnectionProxy也叫做钩子方法,而execute()也就是模板方法