关于在基于spring的框架中使用static 方法的问题

05-08-01 dabb
一般使用spring做框架设计的web 应用中,都是利用Webapplicationcontext这个类做为beanFactory的。而这个类是在启动时加载的。

在应用中可能会有一些helper,或则util类,需要提供静态方法来获取数据,不如DeptHelper.treeListDept()。如果该类要从一个DAO里取数据,那么它该如何访问ioc的beanFactory,以获取这个DAO对象呢?

大家知道WebApplicationContext一般是通过WebApplicationContextUtils

.getRequiredWebApplicationContext(config.getServletContext());来获取的。但是如果我们的DeptHelper.treeListDept()不能获取一个HttpServletRequest或则ServletContext,该怎么办呢?

我想了个办法,就是写一个静态类

ApplicationContextKeeper ,如下:

private static ApplicationContext appCtx = null;

public static ApplicationContext getAppCtx() {

return appCtx;

}

public static void init(ApplicationContext ctxVal) {

appCtx = ctxVal;

}

这个类在系统启动时由一个servlet来初始化(就是调用它的init),例如:

public class ApplicationContextLoadServ extends BaseServ {

public void init(ServletConfig servletConfig) throws ServletException {

ApplicationContext ctx = WebApplicationContextUtils

.getRequiredWebApplicationContext(servletConfig.getServletContext());

ApplicationContextKeeper.init(ctx);

}

public void destroy() {

super.destroy();

}

}

该servlet的启动顺序是在spring的ContextLoaderServlet之后的,这样就保证获取了ApplicationContext。

这样的话我的

DeptHelper.treeListDept()就可以这样写了

{

IDeptInfoDAO deptInfoDAO = (IDeptInfoDAO)ApplicationContextKeeper.getAppCtx().getBean("deptInfoDAO");

deptInfoDAO.listDeptData.....

}

当然我是初次应用,想来也不会有什么问题。大家可以讨论讨论

1
banq
2005-08-01 19:39
问题是没有问题,但是我个人认为你还没有改变一些编程习惯:少用静态或单态。

DeptHelper.treeListDept()中DeptHelper也许不必使用静态,一些涉及数据库的helper类已经不是简单的help工具,属于参与业务逻辑的辅助类,一般这样情况使用设计模式来安排这些类的关系,spring提供了Ioc模式实现。 要参与模式,首先去除静态或单态。

个人意见。仅供参考。

dabb
2005-08-02 14:23
我明白你的意思。这个只是我随手举的例子,倒没有考虑到业务的问题。举个比较合适的例子吧。在一些系统里我们会不可避免的遇到一些类似于factory模式实现cache的例子。比如我会写一个包含类,里面cache一些常用的比较固定不变的数据。比如一些系统标准代码。这些一般很很多业务模块关联在一起,但又不是业务的核心,只是保存一些值。所以提供static方法访问数据是很合适的。

再比如我上面的例子,实际上主要是对部门数据的cache,然后提供一些static方法访问部门数据(例子中名字写的不对,helper让人联想到view的helper了)。类似于这些cache都需要初始化时访问db(通过dao)取的数据。而这些类由ioc管理显然不合适(我不可能为了访问一个标准代码值,而在业务类里弄个get,set 标准代码获取类的实例吧)。按个人经验,实际项目中还是很需要一些静态类的,从编程角度 来说。纯ioc是理想化了。

再举个例子,为了加快开发,我们封装了个专门对数据库crud进行操作的包,也是以static方法发布。通过传递sql及paramenter值作为参数,以实现crud及翻页的通用操作。从设计角度看,当然是不可取的,因为这可能会牵扯到性能或则oo的“法则”问题。但是在普通的应用中,性能问题不大,而且对oo“法则”的影响只是局部细节的。对程序员的开发速度却有了不少提高。这样的static难道不合适吗?

我想bang也是从实际项目角度考虑问题的,要不也不会提出以提高开发速度为目标的jdonframework来。可能是我引用的例子不对,造成误解。

banq
2005-08-02 17:27
这可能是个人风格吧,我个人是很少用static,现在也开始拒绝单态了。

在J2SE中不可避免使用static或单态才能达到目的,但是在J2EE容器中,我们只要将需要单例的对象注册到容器上,也就是状态俗称的三种之一Application,其他两个是Session 和request.

dabb
2005-08-02 19:54
注册到web 容器的context上需要能够访问到相应的context,比如servletcontex,request,session等。但在业务类里面一般都是不能访问到这些组件的。当然在spring里可以通过实现ServletContextAware接口来获取servletContext.但个人感觉一些基础的东西象标准代码之类的每 次都要从servletcontex取出来,再Cast,再取值,还不如一个确定名字的工具类来的方便。而且这个标准代码之类的东西是跨越很多个模块的,这样就要使所有要用到这个标准代码值的业务类都要实现ServletContextAware,这不是显的有点奇怪了。

猜你喜欢