读书人

java项目开发实践经验之三:spring的那

发布时间: 2012-08-31 12:55:03 作者: rapoo

java项目开发实践经验之三:spring的那些事儿
相信spring现在已经成为j2ee开发的首选框架,也深受广大java开发者的喜爱,它的ioc、aop以及各种扩展应用都使开发者受益。它不仅是一个开发框架,同时还把很多优秀的设计理念潜移默化的传递给了使用者...好了,具体spring有多优秀不是这篇文章的重点,以下就谈一下笔者在项目中使用spring的实际经验吧。

1 项目的哪些地方需要用到spring
这应该是一个相当大的话题,不过还是有必要阐述一下。就当前典型的j2ee应用或web应用上流行的mvc(如ssh)框架而言,spring应用在以下几个方面
核心开发框架:spring作为核心容器,通过主要组件BeanFactory并使用ioc实现对所有bean的管理。在实际应用中,首先要秉承接口模式的编程思路,定义应用类之前先定义接口,然后再定义实现类,而调用的时候则调用接口而不是实现类。同时需要配置一个或多个spring的xml配置文件,把调用接口映射到实现类。
dao端的框架支持:在三层框架模式下(web,service,dao),通过HibernateTemplate和JdbcTemplate等支持类,在dao层对jdbc以及Hibernate等主流的ORM数据库调用模式进行支持。一般都有专门的jdbc以及hibernate的配置文件对DAO层使用的bean进行设置。
service端的框架支持:在serivce层通过ioc进行bean的管理配置,同时进行事务控制的定义。
aop:利用拦截器配置管理特性
jndi:利用spring的context组件对jndi进行定义,通常用于数据库连接池的配置和查找
其他:spring1.2版本的mvc组件是针对web端的应用框架,尽管理念非常oop,不过实际使用的时候确实不如struts2好使,spring 2.0以后的mvc据说有很大改进,以后有机会再用吧。另外spring的定时任务(job)也经常用到,后边会有提及。

2 spring的orm组件的使用经验
ssh框架的一个典型应用,通过HibernateTemplate实现spring与hibernate的集成。一般都是通过在配置文件向继承HibernateDaoSupport的dao实现类注入sessionFactory,这个sessionFactory实现类一般被定义为LocalSessionFactoryBean,而LocalSessionFactoryBean这个类也属于spring的hibernate支持包,它的一个重要属性是dataSource,对应的是jdbc的DataSource接口,而这个dataSource又可以通过ioc的方式注入实际的实现类,这个类既可以是各种java连接池的DataSource实现类,也可以是JndiObjectFactoryBean--spring用于进行数据源查找的jndi实现类。综上所述,正式由于这一连串的联系,实现了hibernate模式下的数据库接入。而jdbc模式也是如此联系,不同的是spring使用JdbcTemplate类进行支持。在使用中一些细节需要注意,比如
如何实现批量更新:HibernateTemplate的bulkUpdate方法可以用hql语句直接进行批量更新
对结果列表进行加工:不论通过jdbc还是hibernate方式,如果需要对find方法取得的列表中的对象进行加工,显然使用回调模式进行效率更高。实际上如果使用HibernateTemplate并且希望查询出的结果不是对象列表而是数组列表,那么也可以使用回调,如下:
String hql = "select t.id,t.name from test t";
List list = (List) this.getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws SQLException, HibernateException {
SQLQuery query = session.createSQLQuery(sql);
List children = query.list();
return children;
}
});
Iterator it = list.iterator();
while(it.hasNext()){
Object[] obj = (Object[])it.next();
System.out.println("id:" + obj[0]);
//do some business here
}
如上述代码所示,某些时候我们希望直接使用字段来进行逻辑处理,那么HibernateTemplate的find方法显然是不合适的,而回调模式返回的list中的内容是对象数组
调用存储过程:HibernateTemplate可以通过回调调用存储过程
hibernateTemplate.execute(new HibernateCallback(){
public Object doInHibernate(Session session) throws SQLException{
CallableStatement cs = session.connection().prepareCall("{call usr.someProc}");
cs.executeUpdate();
return null;
}
}
);

3 spring的事务控制
在项目中,一般使用spring的声明式方法控制数据库事务,定义数据库事务只需要通过配置文件中配置即可,这种模式的技术基础是基于AOP的。
事务配置定义:在三层构架中,通常都在service层进行业务逻辑处理,以及事务控制。因此spring在service层可以单独定义一个配置文件,映射service层中使用的bean,并且在定义这个bean的配置同时进行事务声明,有多种方式。最直接的方式是定义这个bean的实现类为TransactionProxyFactoryBean--spring的事务控制代理,这种事务配置可以参见下面的代码例子:
<bean id="someBusinessBean"
abstract="true"
ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop>
<prop key="update*">PROPAGATION_REQUIRED,-MyCheckedException</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="someBusinessBean" parent="txProxyTemplate">
<property name="target">
<bean ref="dao"/>
</bean>
</property>
</bean>
可以看出,这种方式先使用一个父类作为事务控制的统一定义,然后具体的业务bean通过继承来实现事务的配置。其实这2中配置方式并没有本质的区别,只是第二种定义起来会省事一点。
另外在实际项目中有一个发现,在websphere6.0的容器下部署的web应用,使用websphere自带的数据库连接池,当spring事务配置为readOnly,在数据量比较大,并且有一定并发量时会导致websphere连接池抛出异常,并导致性能严重下降。去掉readOnly选项就恢复正常了,这种情况不容易在测试环境重现,因此只能去掉readOnly选项,发现去掉以后性能也没有太多的下降。
另外如果一些特殊的场景直接在代码中进行事务提交(比如大批量插入数据),则需要用到spring的编程事务,PlatformTransactionManager这个类是spring针对编程式事务的支持类。

4 spring与数据库连接池
在spring中可以很方便的配置数据库连接池,一种是直接配置连接池,以proxool连接池为例,配置代码如下:
<bean id="dataSource" 在每天下午2点下午6点期间的每5分钟触发
OpenSessionInView:spring为了支持在页面中延迟加载事务的一个filter,建议谨慎使用,容易对数据库连接性能造成瓶颈

总结:以上列举了一些项目中使用spring的地方,相信还有更多的没有列举出来,在以后的文章里再补充吧

广告时间: 轻松阅读,尽在阅读地带
1 楼 xylsh7456 2010-10-28 写的挺好的,支持楼主,等待楼主待续。。。

读书人网 >软件架构设计

热点推荐