AppFuse中Spring的配置
 
2008-12-22 来源:blogjava.net
 

Spring中,BeanFactory提供了一种先进的配置机制来管理任何种类bean(对象), ApplicationContext是BeanFactory的完全超集,我们大部分时间面对的是ApplicationContext,通过它取得bean,处理bean,而其他的事务管理、远程访问等则交由Spring容器去管理好了。很多情况下,用户代码不需要实例化BeanFactory, 因为Spring框架代码会做这件事。例如,web层提供支持代码,在J2EE web应用启动过程中自动载入一个Spring ApplicationContext。

ApplicationContext可以通过编码加载并实例化,对于web应用,Spring提供了可配置的ApplicationContext加载机制。加载器目前有两种选择:

1 : ContextLoaderListener  (基于Servlet2.3版本中新引入的Listener接口实现)

2 : ContextLoaderServlet   (基于Servlet接口实现)

这两者在功能上完全相同

AppFuse中的Spring配置

(1)指定ApplicationContext配置文件的位置,该参数不是必须的如果不指定该参数,web容器会自动加载 WEB-INF/applicationContext.xml, 并实例化ApplicationContext

WEB-INF/web.xml

1 < context - param >  
2         < param - name > contextConfigLocation </ param - name >  
3         < param - value >/ WEB - INF / applicationContext -* .xml </ param - value >  
4 </ context - param >  

(2)AppFuse中的ApplicationContext加载是通过ContextLoaderListener配置实现的,但是AppFuse不是直接在web.xml配置ContextLoaderListener监听器来实现ApplicationContext的初始化的,而是通过自定义的StartupListener监听器实现配置的。

(3)ApplicationContext的初始化StartupListener 继承了Spring的 ContextLoaderListener接口,并实现:Sevelet的ServletContextListener接口

Web容器启动时,执行StartupListener监听器 StartupListener监听器执行父类ServletContextListener的contextInitialized事件,在该初始化事件中,会调用Spring的contextInitialized事件初始化Spring的ApplicationContext。

1 public   class  StartupListener  extends  ContextLoaderListener  implements  ServletContextListener 
2      public   void  contextInitialized(ServletContextEvent event) 
3              // 调用Spring的contextInitialized事件初始化Spring的ApplicationContext 
4             super .contextInitialized(event); 
5
6        .
7
8      }

9 }

(4) 初始化完ApplicationContext后,就可以通过以下方式引用ApplicationContext来管理beans了:      

1 ApplicationContext ctx  =    WebApplicationContextUtils.getRequiredWebApplicationContext(context); 

(5)Spring事务管理配置 

Spring即提供了对于JDBC,Hibernate Trasaction等依赖特定事务资源的事务处理(即:自己硬编码rollback、commit), 又提供了依赖容器的参数化事务支持(即:又Spring容器管理事务)。使用Hibernate提供的openSessiojnInView技术,即在视图层开启和关闭 Session,在service层进行Transaction管理,这个较为简单,只需要设置一个filter即可,在web.xml中配置

1 < filter >  
2      < filter - name > hibernateFilter </ filter - name >  
3      < filter - class > org.springframework.orm.hibernate.support.OpenSessionInViewFilter </ filter - class >  
4 </ filter >  

(6)配置数据源,这里采用Jndi访问方式。

1 < bean id = " dataSource "    class = " org.springframework.jndi.JndiObjectFactoryBean " >  
2       < property name = " jndiName " >  
3            < value > java:comp / env / jdbc / dudu </ value >  
4       </ property >  
5 </ bean >  

(7)配置SessionFactory,

Hibernate通过SessionFactory创建和维护session,一个session代表了以此数据的访问回话。通过Spring我们就无须通过Hibernage.cfg.xml对SessionFactory进行设定。SessionFactoryj节点的mappingResources属性包含了映射文件的路径。

hibernateProperties节点容纳了所有的属性配置。

 1 < bean id = " sessionFactory "   class = " org.springframework.orm.hibernate3.LocalSessionFactoryBean " >
 2       < property name = " dataSource "  ref = " dataSource " />
 3       < property name = " mappingResources " >
 4           < list >
 5                < value > org / appfuse / model / Role.hbm.xml </ value >
 6                < value > org / appfuse / model / User.hbm.xml </ value >
 7           </ list >
 8       </ property >
 9       < property name = " hibernateProperties " >
10           < props >
11                < prop key = " hibernate.dialect " > @HIBERNATE - DIALECT@ </ prop >
12                < prop key = " hibernate.query.substitutions " > true   ' Y ' false   ' N ' </ prop >
13                <!--  Create / update the database tables automatically when the JVM starts up
14                < prop key = " hibernate.hbm2ddl.auto " > update </ prop >   -->
15                <!--  Turn batching off  for  better error messages under PostgreSQL 
16                < prop key = " hibernate.jdbc.batch_size " > 0 </ prop >   -->
17           </ props >
18       </ property >
19 </ bean >

(8)配置事务管理,引用sessionFactory。

1 < bean id = " transactionManager "   class = " org.springframework.orm.hibernate3.HibernateTransactionManager " >
2        < property name = " sessionFactory "  ref = " sessionFactory " />
3 </ bean >

(9)配置dataSource、sessionFactory、transactionManager服务器于名为txProxyTemplate的TransactionProxyFactoryBean, txProxyTemplate的transactionAttributes属性中,定义事务策略。将所有以save、remove开始的方法纳入事务管理范围,如果这些方法抛出异常,在Spring将当前事务回滚,如 果方法正常结束,则提交事务。而对其他所有的方法则以只读的事务处理机制进行,(设为只读性事务,可以是持久层尝试对数据操作进行优化,如对于只读事务hibernate将不执行flush操作,而某些数据库连接池和JDBC驱动也对只读性操作进行了优化), TransactionProxyFactoryBean使得我们可以脱离每次数据库操作必须首先获得Session实例、启动事务、提交、回滚事务以及繁琐的try/catch/finally的烦杂工作从而获得代码精干集中的逻辑呈献效果。org.springframework.transaction.interceptor.TransactionProxyFactoryBean
利用AOP,将TransactionManager和普通的Service编织起来。 

 1 < bean id = " txProxyTemplate "   abstract = " true "   class = " org.springframework.transaction.interceptor.TransactionProxyFactoryBean " >
 2      < property name = " transactionManager "  ref = " transactionManager " />
 3      < property name = " transactionAttributes " >
 4          < props >
 5             < prop key = " save* " > PROPAGATION_REQUIRED </ prop >
 6             < prop key = " remove* " > PROPAGATION_REQUIRED </ prop >
 7             < prop key = " * " > PROPAGATION_REQUIRED,readOnly </ prop >
 8          </ props >
 9      </ property >
10 </ bean >

(10)   实际的事务处理模板定义

AppFuse没有直接使用txProxyTemplate来管理事务,而是由具体的管理类继承该类,完成具体事务管理。

 1 <!--  可以应用在任何对象上进行基本的CRUD操作的 顶级的 manager  -->
 2 < bean id = " manager "  parent = " txProxyTemplate " >
 3        < property name = " target " >
 4         < bean  class = " org.appfuse.service.impl.BaseManager " >
 5          < property name = " dao "  ref = " dao " />
 6         </ bean >
 7        </ property >
 8 </ bean >
 9
10
11 < bean id = " userManager "  parent = " txProxyTemplate " >
12        < property name = " target " >
13         < bean  class = " org.appfuse.service.impl.UserManagerImpl " >
14          < property name = " userDao "  ref = " userDao " />
15         </ bean >
16        </ property >
17        < property name = " transactionAttributes " >
18         < props >
19          < prop key = " save* " > PROPAGATION_REQUIRED, - UserExistsException </ prop >
20          < prop key = " remove* " > PROPAGATION_REQUIRED </ prop >
21          < prop key = " * " > PROPAGATION_REQUIRED,readOnly </ prop >
22         </ props >
23        </ property >
24        < property name = " preInterceptors " >
25         < list >
26          < ref bean = " userSecurityInterceptor " />
27         </ list >
28        </ property >
29 </ bean >

(11)   数据访问形式

1   public   class  UserDAOHibernate  extends  BaseDAOHibernate  implements  UserDAO 
2         public   void  saveUser( final  User user) 
3         getHibernateTemplate().saveOrUpdate(user); 
4         getHibernateTemplate().flush(); 
5        }
 
6 }
 

(12)以下是一些AppFuse中实现的,辅助的Spring监听器和过滤器

保证Spring所管理的JavaBeans能被正常的初始化和销毁,这个监听器不是 Spring框架必须的。

 WEB-INF/web.xml

1 < listener >  
2      < listener - class >  
3         org.springframework.web.util.IntrospectorCleanupListener 
4      </ listener - class >  
5 </ listener >  

(13) 解决Web应用中POST的中文乱码问题,为用户请求定义字符编码,这是因为当前的浏览器一般都不设置字符编码,即便是你在Html文件获Form中设置了字符编码 

WEB-INF/web.xml

 1 < filter >
 2      < filter - name > encodingFilter </ filter - name >
 3      < filter - class > org.springframework.web.filter.CharacterEncodingFilter </ filter - class >
 4      < init - param >
 5          < param - name > encoding </ param - name >
 6          < param - value > UTF - 8 </ param - value >
 7      </ init - param >
 8      < init - param >
 9          < param - name > forceEncoding </ param - name >
10          < param - value > true </ param - value >
11      </ init - param >
12 </ filter >

注:一般的web容器加载Spring的ApplicationContext配置如下:

通过监听器

1 < listener >  
2      < listener - class >  
3         org.springframework.web.context.ContextLoaderListener 
4      </ listener - class >  
5 </ listener >  

或通过Servlet

1 < servlet >  
2           < servlet - name > context </ servlet - name >  
3           < servlet - class >  
4         org.springframework.web.context. ContextLoaderServlet 
5           </ servlet - class >  
6           < load - on - startup > 1 </ load - on - startup >  
7 </ servlet >  

火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织