论坛首页 Java企业应用论坛

Struts调用Spring服务类的三种方法

浏览 11463 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-09-15  
  用SSH做了几个项目,现在总结一下Struts Action中调用Spring Service的方法,大家有好的实现,请继续补充:

  1.老爸操持型
    这种类型,即是在BaseAction中提供一个getBean(String beanName)的父类方法,业务Action 在需要Serivce时,调用父类的getBean()得到Object型的Service,再Cast。
   e.g.
  public class BaseAction extends DispatchAction
  {
     ... 
     public Object getBean(String name)
    {
        if (ctx == null)
        {
            ctx = WebApplicationContextUtils
                  .getRequiredWebApplicationContext(servlet.getServletContext());
        }
        return ctx.getBean(name);
    }
  }


  2.自已动手型
   自己动手 丰衣足食,再加了自从有了IoC,所谓动手也只是衣来后的伸手和饭来后的张口。自己动手型,即是利用Spring的IoC,将IoC容器中的Service注入到Action中,当然Action需要提供注入服务有setter.
   如果采用这种方式,首先需要让Spring接管Struts,然后在Spring配置文件中,配置Action的注入属性。
   首先.在struts-config.xml将Spring引狼入室。
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> 
        <set-property property="contextConfigLocation" 
                                  value="/WEB-INF/action-servlet.xml" 
        /> 
</plug-in> 

  然后,Struts再向Spring投怀送抱:
<bean id="userService" class="com.nic.service.UserServiceImpl">
    <property name="userDao">
	<ref bean="userDao" />
    </property>
</bean>	
<bean name="/userAction" class="com.stamen.web.UserAction">
   <property name="userService" ref="userService"/>
</bean>
   
   聪明的你一下就看出“/userAction ”即是com.stamen.web.UserAction在Struts中的配置名。
 
3.朋友帮忙型  朋友多了好办事,凡事都自己动手总有一天会活活累死,所有Action为自己需要的Service提供setter,并且在Spring中注入,好累啊。小学生都在减负了,我们也来为Action减减负吧--提供一个专门
查找Serivice的ServiceLocator,负责获取所有的Service,该类为每个Service提供专门的获得方法,如:
  public class ServiceLocator
{
    private static ApplicationContext factory = null;
    public static void init(ApplicationContext ctx)
    {    
        factory = ctx;
    }
    public static LogService getLogService()
    {
        return (LogService) ServiceLocator.getBean("logService");
    }

    public static UserService getUserService()
    {
        return (UserService) ServiceLocator.getBean("userService");
    }
    public static PieeService getPieeService()
    {
        return (PieeService) ServiceLocator.getBean("pieeService");
    }
    public static PieeGrid getPieeListService()
    {
        return (PieeGrid) ServiceLocator.getBean("pieeListService");
    }
    ...
 } 


    Action要用哪个Serivce时,直接通过ServiceLocator.getXxxService()就可以获得了,省去了
“老爸操持型”指定Service 名和Cast的繁琐,比在Spring中IoC来IoC去也来得省心省力。
   
   下面做一个自己的分析小结:
1.“老爸操持型” 将serviceName分散到代码中,到时配置文件中serviceName一改,得牵一毛而动全身->维护性差;且要进行Cast转换,怎一个繁字了得。
2.“自己动手型”也不好,不但在Action中要添加get/setXxxService代码,而且还要在Struts和Spring的配置文件中做好群众的大串连工作,难道我们的配置还不够多吗?吃回香豆的,你别又跳出来啊:)
3.“朋友帮忙型”,目前,我认为是比较好的方式,ServiceLocator象一个服务周到,工作到位的房产“中介”,我们要租房子 何必满街跑啊?TMD 这个月我又交了3K房租,也不知道李大伦,李金宝之流规矩后,房价能不能降些,我想有个蜗牛的家 已经唱了好几年了--跑题了,睡觉去了:)
 
   发表时间:2006-09-16  
什么是注入?你有看到Spring的IoC依赖于Spring的代码嘛?再想想再评论。

Spring2.0提供了autowire的注入方式,值得借鉴,我已经开过一贴,论坛中搜索一下。
0 请登录后投票
   发表时间:2006-09-16  
downpour 写道
什么是注入?你有看到Spring的IoC依赖于Spring的代码嘛?再想想再评论。

   我并没有说Action依赖于Spring,“自己动手型”时,每个需要用到Service的Action需要提供Service的get/setter方法,并且在Struts和Spring的配置文件中都需要设置,毕竟带了挺多的工作。此外还将Action的类变得更不清晰。
 
downpour 写道
Spring2.0提供了autowire的注入方式,值得借鉴,我已经开过一贴,论坛中搜索一下。

   autowire是个不错的东西,可以省除Spring中部分的配置
信息,但是凡事有得必有失,它是以规范命名和默认契约为前提的。它一方面减少配置,一方面有模糊了配置的清晰度,一般情况下,在小型的项目或测试时可以使用,在大型的项目,需要充分沟通和协调的项目里,autowire并不推荐使用。
0 请登录后投票
   发表时间:2006-09-16  
三种都是方法,在评价哪个好,哪个不怎么好的时候,每个人有不同的标准。我的标准就是我的Java代码尽量不要依赖于Spring的代码进行测试。这也是引入Spring的ApplicationContext对你的Bean进行管理的原因,你的业务逻辑代码将不依赖于容器。

stamen 写道

autowire是个不错的东西,可以省除Spring中部分的配置
信息,但是凡事有得必有失,它是以规范命名和默认契约为前提的。它一方面减少配置,一方面有模糊了配置的清晰度,一般情况下,在小型的项目或测试时可以使用,在大型的项目,需要充分沟通和协调的项目里,autowire并不推荐使用。


autowire提供了多种方式,byName,byType等等,我不清楚你所说的“模糊了配置的清晰度”是啥意思,也不清楚你所说的大型项目中,需要充分沟通和协调的项目是什么样的项目?到底需要那些默认契约?我们所有的项目都在用autowire,好像没有听说有什么默认契约嘛。


0 请登录后投票
   发表时间:2006-09-16  
引用
autowire提供了多种方式,byName,byType等等,我不清楚你所说的“模糊了配置的清晰度”是啥意思,也不清楚你所说的大型项目中,需要充分沟通和协调的项目是什么样的项目?到底需要那些默认契约?我们所有的项目都在用autowire,好像没有听说有什么默认契约嘛。

    byName时契约就是属性名和Bean名必须相同,byType时契约就是属性类型和Bean类型必须相同,Spring又不是神仙,它哪里知道你的心理想什么,还不是根据这些契约或说协议来自动装配的。
     但是这种装配,你得在命名上小心谨慎,否则可以就把该装配的没有装配上,不该装配的装配进去了。
一个大项目的Service ,Dao数量是很大的,很容易就张冠李戴,弄巧成拙了。此外,大项目有多个开发人员同时做,在命名时就要约定好,否则,Bean的属性名得遵照规矩走,难道这不是沟通成本吗。
0 请登录后投票
   发表时间:2006-09-16  
和此人无法交流了。

哪位老大来给他讲讲啥叫byType。偶实在还是不能理解在大家使用同一个接口时,需要啥交流?
0 请登录后投票
   发表时间:2006-09-16  
downpour 写道
和此人无法交流了。

哪位老大来给他讲讲啥叫byType。偶实在还是不能理解在大家使用同一个接口时,需要啥交流?

  看来Downpour最近心情不好,首先是叫我学习IoC,然后再开口讲话,现在又要叫大家给我上ByType的课,对我进行学前教育。你心情不好,大家都可以理解,但没有必须动不动就暴粗口,影响美好氛围的同时,也并不会有利于你心情的好转
0 请登录后投票
   发表时间:2006-09-16  
各有千秋吧,无论是byName,byType还是用autowire...等等,虽然简化了自己写配置文件的时间,但是条理不清晰,不方便测试,重构代码的时候要求注入的对象名还不能变,一变就挂了,至于楼主所说的三种方法,我常用第二种,第三种也要写死呀,还不如配置文件算了,反正写一句也是写
0 请登录后投票
   发表时间:2006-09-16  
downpour 写道
偶实在还是不能理解在大家使用同一个接口时,需要啥交流?

    我来给你举两个例子,同样的一个UserDao接口,该UserDao需要访问两个DB,所以在Spring中会配置两个,一个叫userDao1 访问DB1,另一个叫userDao2 访问DB2,这时,如果你用byType难道还不要交流吗?
    另一个例子,我有两个JavaMailSender,一个叫sender1用于发送系统的Mail,另一个叫sender2,用于发送业务的Mail(所用的邮件服务器,用户密码均不一样),需要注入JavaMailSender的服务类,直接用byType还能成吗?
    在大型的系统中,并非一个接口只会在IoC中出现一次,这两个例子,目前我的系统都有出现,所以我才会说byType和byName是不适合在大型系统中用的。
0 请登录后投票
   发表时间:2006-09-16  
嗨~~  本来不想再说啥了,既然你喋喋不休,我也再说两句。

userDAO访问两个数据库,本身就针对了两个userDAOImpl,两个sessionFactory。此时你居然可以只设计一个接口?我不懂了,假设你这个接口中有个getUserByName,针对的是DB1。你的UserDAOImpl1实现了这个函数,UserDAOImpl2实现这个函数的时候你写的啥?

退一步,byType可以解决绝大多数问题,类似多个实现的情况,一般byName会起到作用。如果针对两个不同的实现,你都要取同样的名字,那我实在是无话可说了。

PS. 不晓得你哪里看到我说过粗话?如果找不到,请修改你的言语。
0 请登录后投票
论坛首页 Java企业应用版

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