精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-10-29
要想在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在两个配置文件中都出现了,带来一些额外代码。不过我认为这个代价是可以承受的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-10-29
我倾向于前者,我们需要对Action进行事务控制么,Action应该由ActionServlet管理
|
|
返回顶楼 | |
发表时间:2004-10-29
不光是transaction,也可以做其他的事情,比如proxy亦可。
|
|
返回顶楼 | |
发表时间:2004-10-29
上一次开发我选择了前者。
如果我知道有后者的话,毫无疑问我会选择后者。 前者在测试的时候会有些麻烦! |
|
返回顶楼 | |
发表时间:2004-10-29
我是不同意后者的,这样做法的耦合性太高了,层次不够分明,逻辑不够清楚。并且给Action提供过多的功能也不是太必要,如果真需要那么多功能,就不如放到Spring Service里面来处理。
|
|
返回顶楼 | |
发表时间: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);; } } |
|
返回顶楼 | |
发表时间: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的代码? |
|
返回顶楼 | |
发表时间: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。 |
|
返回顶楼 | |
发表时间:2004-10-29
偶在实际项目中用前者, 不用spring来管理action的理由只有一个:
写WebWork action和页面的人不需要了解和学习spring的相关知识和配置. |
|
返回顶楼 | |
发表时间:2004-10-29
to readonly: 那你权限控制是做在哪里的?
|
|
返回顶楼 | |