论坛首页 Java企业应用论坛

webwork2 action和Spring结合的两种方式

浏览 34721 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-10-29  
webwork2和spring的功能有一些是重叠的,有一些则是可以互补的。xwork + webwork在处理action的时候层次清楚,action-chain和interceptor的结构清晰优雅,比struts不知道强了多少。
要想在action里面使用spring的bean,比如说,在一个action中使用一个DAO,可以有两种方式,一是
http://wiki.opensymphony.com/display/WW/WebWork+2+Spring+Integration 这样的方法,使用<external-ref name="DAO">myDAO</external-ref>的方式,再通过一个interceptor在action被调用之前注射DAO。

另一种方式是http://wiki.opensymphony.com/display/WW/Spring  ,通过把action也作为bean放在spring的applicationContext中定义。xwork在初始化action的时候,从spring bean factory中获取action而非自己创建。

我倾向于使用后者。把action放在spring的配置文件中,显然可以利用spring的通用的引用机制进行统一维护。比如说,对action声明transaction。如果只是利用external-ref来对action进行注射,显然灵活性少了很多。
缺点呢?就是action在两个配置文件中都出现了,带来一些额外代码。不过我认为这个代价是可以承受的。
   发表时间:2004-10-29  
我倾向于前者,我们需要对Action进行事务控制么,Action应该由ActionServlet管理
0 请登录后投票
   发表时间:2004-10-29  
不光是transaction,也可以做其他的事情,比如proxy亦可。
0 请登录后投票
   发表时间:2004-10-29  
上一次开发我选择了前者。
如果我知道有后者的话,毫无疑问我会选择后者。
前者在测试的时候会有些麻烦!
0 请登录后投票
   发表时间:2004-10-29  
我是不同意后者的,这样做法的耦合性太高了,层次不够分明,逻辑不够清楚。并且给Action提供过多的功能也不是太必要,如果真需要那么多功能,就不如放到Spring Service里面来处理。
0 请登录后投票
   发表时间:2004-10-29  
firebody 写道
上一次开发我选择了前者。
如果我知道有后者的话,毫无疑问我会选择后者。
前者在测试的时候会有些麻烦!


不麻烦,看下面的代码:

import junit.framework.TestCase;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate.SessionFactoryUtils;
import org.springframework.orm.hibernate.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import com.opensymphony.xwork.config.Configuration;
import com.opensymphony.xwork.config.ConfigurationManager;
import com.opensymphony.xwork.config.entities.PackageConfig;
import com.atlassian.xwork.ext.ServletContextAware;
import com.atlassian.xwork.ext.SpringApplicationContextAware;

import java.util.Iterator;

public abstract class AbstractTest extends TestCase {

    //todo: maybe user serviceLocator?
    protected static BeanFactory beanFactory;

    private SessionFactory sessionFactory;
    private Session session;

    protected void setUp(); throws Exception {
        if (beanFactory == null); {
            beanFactory = new ClassPathXmlApplicationContext("/WEB-INF/applicationContext.xml");;
            initExternalReferenceResolver();;
        }
        sessionFactory = (SessionFactory); beanFactory.getBean("sessionFactory");;
        session = SessionFactoryUtils.getSession(sessionFactory, true);;
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session););;
    }

    private void initExternalReferenceResolver(); {
        Configuration config = ConfigurationManager.getConfiguration();;
		String key;
		PackageConfig packageConfig;
        for(Iterator iter = config.getPackageConfigNames();.iterator();; iter.hasNext();; );
        {
            key = (String);iter.next();;
			packageConfig = config.getPackageConfig(key);;
			if(packageConfig.getExternalRefResolver(); instanceof SpringApplicationContextAware);
			{

			     ((SpringApplicationContextAware);packageConfig.getExternalRefResolver(););.setApplicationContext(
                         (ApplicationContext); beanFactory);;
			}

        }

    }

    protected void tearDown(); throws Exception {
        TransactionSynchronizationManager.unbindResource(sessionFactory);;
        SessionFactoryUtils.closeSessionIfNecessary(session, sessionFactory);;
    }
}


测试用例:
import com.opensymphony.xwork.ActionProxyFactory;
import com.opensymphony.xwork.ActionProxy;
import com.opensymphony.xwork.ActionContext;

import java.util.HashMap;
import java.util.Map;

import junit.framework.TestCase;

/**
 * User: femto
 * Date: 2004-10-21
 */
public class RegisterActionTest extends AbstractTest {
    public void testExecuteWithProxyFactory(); throws Exception{

            Map params = new HashMap();;
            params.put("user.username","Moxie");;
            params.put("user.password","mypassword");;
            params.put("user.email","achqian@yahoo.com.cn");;
            params.put("user.age",new Integer(23););;
            Map extraContext = new HashMap();;
            extraContext.put(ActionContext.PARAMETERS,params);;

            ActionProxy proxy = ActionProxyFactory.getFactory();.createActionProxy(null, "test", extraContext);;
            proxy.setExecuteResult(false);;
            assertEquals(proxy.execute();,"success");;

            TestAction action = (TestAction); proxy.getAction();;
            assertEquals(action.getUser();.getUsername();,"Moxie");;
            assertEquals(action.getUser();.getAge();,23);;
        }

}
0 请登录后投票
   发表时间:2004-10-29  
不懂得大家选择前者是怎么测试的?
我用了一个比较笨的办法来测试action:
引用
protected void setUp() throws Exception {
super.setUp();
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"com/eibm/persistence/applicationContext-dao.xml");
sessionFactory = (SessionFactory) ctx.getBean("sessionFactory");
session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.NEVER);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
Configuration config = ConfigurationManager.getConfiguration();
String key;
PackageConfig packageConfig;
for (Iterator iter = config.getPackageConfigNames().iterator();
iter.hasNext();) {
key = (String) iter.next();
packageConfig = config.getPackageConfig(key);
if (packageConfig.getExternalRefResolver() instanceof ServletContextAware) {
((SpringApplicationContextAware) packageConfig.getExternalRefResolver()).setApplicationContext(ctx);
}
}
dao=(EntityDAO)ctx.getBean("dao");


}

哇哇,没想到robbin那么快的动作!
不知道大家伙还有更好的测试方法吗?怎么可以减少这些注入ctx的代码?
0 请登录后投票
   发表时间:2004-10-29  
说到耦合性,external ref和object bean factory的区别并不大。
说到多余代码,如果考虑到一个action可能多次应用external-ref,代价和在applicationcontext里面注册action类哪个高也说不定。

从一些更广的范围来考虑,能够利用spring来管理action是让我认为后者比前者更好的原因。

比如使用aop进行acl控制,如果把action也作为spring bean,就很容易加以proxy。

虽然xwork本身和spring有所重叠,但是我看中webwork只是作为spring的前端,spring本身是各种功能的结合点,如果把acl做成webwork的interceptor,我看不到比做在spring中有更多的优势。

本质上前者是external reference,而后者是spring enabled action。
0 请登录后投票
   发表时间:2004-10-29  
偶在实际项目中用前者, 不用spring来管理action的理由只有一个:
写WebWork action和页面的人不需要了解和学习spring的相关知识和配置.
0 请登录后投票
   发表时间:2004-10-29  
to readonly: 那你权限控制是做在哪里的?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics