spring中常⽤的⼏种设计模式
1、简单⼯⼚模式
⼜叫做静态⼯⼚⽅法(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>
2、⼯⼚⽅法模式
通常由应⽤程序直接使⽤new创建新的对象,为了将对象的创建和使⽤相分离,采⽤⼯⼚模式,即应⽤程序将对象的创建及初始化职责交给⼯⼚对象。
⼀般情况下,应⽤程序有⾃⼰的⼯⼚对象来创建bean.如果将应⽤程序⾃⼰的⼯⼚对象交给Spring管理,那么Spring管理的就不是普通的bean,⽽是⼯⼚Bean。
就以⼯⼚⽅法中的静态⽅法为例讲解⼀下:
import java.util.Random;
public class StaticFactoryBean {
public static Integer createRandom() {
return new Integer(new Random().nextInt());
}
}
建⼀个配置⽂件,将其纳⼊Spring容器来管理,需要通过factory-method指定静态⽅法名称:
<bean id="random"
class="example.chapter3.StaticFactoryBean" factory-method="createRandom"
scope="prototype"
/>
测试:
public static void main(String[] args) {
//调⽤getBean()时,返回随机数.如果没有指定factory-method,会返回StaticFactoryBean的实例,即返回⼯⼚Bean的实例
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("l"));
System.out.println("我是IT学习者创建的实例:"+Bean("random").toString());
}
3、单例模式
保证⼀个类仅有⼀个实例,并提供⼀个访问它的全局访问点。
spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例,这是因为spring管理的是是任意的java对象。
核⼼提⽰点:Spring下默认的bean均为singleton,可以通过singleton=“true|false” 或者 scope="?"来指定。
4、适配器模式
在Spring的Aop中,使⽤的Advice(通知)来增强被代理类的功能。Spring实现这⼀AOP功能的原理就使⽤代理模式(1、JDK动态代理。2、CGLib字节码⽣成技术代理。)对类进⾏⽅法级别的切⾯增强,即,⽣成被代理类的代理类, 并在代理类的⽅法前,设置,通过执⾏重的内容增强了代理⽅法的功能,实现的⾯向切⾯编程。
Adapter类接⼝:Target
public interface AdvisorAdapter {
boolean supportsAdvice(Advice advice);
MethodInterceptor getInterceptor(Advisor advisor);
} MethodBeforeAdviceAdapter类,Adapter
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) Advice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
5、包装器模式
在我们的项⽬中遇到这样⼀个问题:我们的项⽬需要连接多个数据库,⽽且不同的客户在每次访问中根据需要会去访问不同的数据库。我们以往在spring和hibernate框架中总是配置⼀个数据源,因⽽sessionFactory的dataSource属性总是指向这个数据源并且恒定不变,所有DAO在使⽤sessionFactor
y的时候都是通过这个数据源访问数据库。
但是现在,由于项⽬的需要,我们的DAO在访问sessionFactory的时候都不得不在多个数据源中不断切换,问题就出现了:如何让sessionFactory在执⾏数据持久化的时候,根据客户的需求能够动态切换不同的数据源?我们能不能在spring的框架下通过少量修改得到解决?是否有什么设计模式可以利⽤呢?
⾸先想到在spring的applicationContext中配置所有的dataSource。这些dataSource可能是各种不同类型的,⽐如不同的数据库:Oracle、SQL Server、MySQL等,也可能是不同的数据源:⽐如apache 提供的org.apachemons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。然后sessionFactory根据客户的每次请求,将dataSource属性设置成不同的数据源,以到达切换数据源的⽬的。
spring中⽤到的包装器模式在类名上有两种表现:⼀种是类名中含有Wrapper,另⼀种是类名中含有Decorator。基本上都是动态地给⼀个对象添加⼀些额外的职责。
6、代理模式
为其他对象提供⼀种代理以控制对这个对象的访问。 从结构上来看和Decorator模式类似,但Proxy是控制,更像是⼀种对功能的限制,⽽Decorator是增加职责。
spring的Proxy模式在aop中有体现,⽐如JdkDynamicAopProxy和Cglib2AopProxy。
7、观察者模式
定义对象间的⼀种⼀对多的依赖关系,当⼀个对象的状态发⽣改变时,所有依赖于它的对象都得到通知并被⾃动更新。
spring中Observer模式常⽤的地⽅是listener的实现。如ApplicationListener。
8、策略模式
定义⼀系列的算法,把它们⼀个个封装起来,并且使它们可相互替换。本模式使得算法可独⽴于使⽤它的客户⽽变化。
spring中在实例化对象的时候⽤到Strategy模式
在SimpleInstantiationStrategy中有如下代码说明了策略模式的使⽤情况:
9、模板⽅法模式
定义⼀个操作中的算法的⾻架,⽽将⼀些步骤延迟到⼦类中。Template Method使得⼦类可以不改变⼀个算法的结构即可重定义该算法的某些特定步骤。
Template Method模式⼀般是需要继承的。这⾥想要探讨另⼀种对Template Method的理解。spring中的JdbcTemplate,在⽤这个类时并不想去继承这个类,因为这个类的⽅法太多,但是我们还是想⽤到JdbcTemplate已有的稳定的、公⽤的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出来作为⼀个参数传⼊JdbcTemplate的⽅法中。但是变化的东西是⼀段代码,⽽且这段代码会⽤到JdbcTemplate中的变量。怎么办?那我们就⽤回调对象吧。
在这个回调对象中定义⼀个操纵JdbcTemplate中变量的⽅法,我们去实现这个⽅法,就把变化的东西集中到这⾥了。然后我们再传⼊这个回调对象到JdbcTemplate,从⽽完成了调⽤。这可能是Template Method不需要继承的另⼀种实现⽅式。
以下是⼀个具体的例⼦:
JdbcTemplate中的execute⽅法
JdbcTemplate执⾏execute⽅法
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论