关于Spring的思考和项目的去Spring尝试


首先,声明一下自己的立场,我不是spring的反对者,顶多算是个质疑者,本文仅仅是对于过去的经验的对比和思考,没有任何反对Spring的意思在里面。 -- 汗啊,带砖头进来的同学可以先放下了。



下面开始正文:

首先要说的是思考的基础,任何框架或者语言,或者工具,我们选择他们的基础应该是他们对我们提供了什么帮助,让我们的工作和生活有了什么质的提升(ps:表激动,这是我的真实想法)。

好吧从这个基础开始我们来看一下spring究竟带给我们什么:

1. IOC控制翻转,这个就是spring翻来覆去在讲的一个东西,don't call me I will call you.

就是说在运行期间才会决定具体的类之间的调用和依赖关系。很炫,而且有好莱坞坐镇。可是真正的作用何在?

简单的想一下自己写的代码,如果没有spring的话我会直接在代码中new一个对象出来,这里面所产生的一个问题也就是在代码的调用的过程中,这些类会被翻来覆去的new出来,所以大家才想到了要进行单例,可是单例和抽象类加static方法自始至终都是一对死冤家,而且话说我觉着用static的话会减少实际的运行时方法查找的次数,对效率还会有提升的。用static的不好处之一是不OO,用java不用面向对象的思想的话好像还不如去写C。好吧,暂时当我们用OO的概念打倒了static(实际上OO对于bs所带来的好处到底是什么到目前感觉还不是很清楚)。既然static不OO那么我们就应该使用new出来的对象,这时候出现的一个问题就是对象变多,占用过多的堆内存,方法栈频繁释放之后对象的频繁回收之类的问题,所以我们现在需要一个单例。好吧到了spring起作用的地方了,运行时的function类的单例缓存。(顺便提一下,static的方法调用,如果想使用反射进行运行时参数设定会有问题,所以这也是支持使用单例的一个原因。)

好吧,我是不是说的有点儿远呢?从IOC扯到了这么多,实际上不是,实际上所有的这些都是为了说明IOC真正带给我们的好处,我所能想到的唯一的好处就是帮我产生了一个缓存的单例对象,但是为了这个单例对象我要做的是需要增加所有的spring的依赖包(这玩意让我的项目变的臃肿不堪),到处增加对于spring使用的声明(各种annotation各种xml配置,让我总感觉项目会散架,而且随时可能产生的命名冲突和配置错误总是让我提心吊胆),还有一个很长很长的学习曲线以及需要跟随潮流升级框架版本的时候带来的种种错误等等。

好吧,我要说的是enough,我的时间不是用来一直学习来对抗这种对于未知的学习和恐惧的,我的时间应该是用来向前看,不停的创造出值得自己炫耀和自豪的东西的。

当然了,到这里还不能完全说明为什么spring不是那么好,毕竟它产生了一个单例,不需要我们再去写那么多的单例代码不是吗?别着急,我们慢慢来,下面是一个单例的实例:

public class MyBean {

  private static MyBean instance = null;

  private MyBean(){

  //do something

  }

  public static synchronized MyBean getInstance(){

  if(instance == null){

  instance = new MyBean();

  }

  return instance;

  }

  }

这是一个最简单而且拥有众多错误的单例,因为它没有实现同步,所以可能出现诸多错误,这里不再分析。下面是一个修改版,使用JVM的ClassLoader的机制进行了同步:

public class MyBean {

  private static MyBean instance = new MyBean();

  private MyBean(){

  //do something

  }

  public static synchronized MyBean getInstance(){

  return instance;

  }

  }

好处坏处都很明显,没有lazyload,但是避免了多个对象的产生。这是一个基本能用的单例,如果我们的类只是功能性的类的话(没有类属性之类的,就是那种无状态的bean,spring托管的那种),那么这种实现已经足够好了,到目前为止我所想要说的是,spring实现给我们的单例,我们自己写起来也不是太麻烦不是嘛?那么它的单例的好处何在?



下面为了维护spring的作用不得不引出spring的第二个大的特性,AOP,传说中的切面编程。

spring提供给我们的单例实际上不是简单的new出来一个对象然后注入到我们的bean里面,它产生的是一个代理对象,我们在实际进行方法调用的时候所调用的也是这个代理的对象,这时候在我们进行真正的方法调用的时候spring可以帮我们多做一点事情,此即AOP。就是说本来该调用a类的1方法,现在调用的proxy$a的1方法,然后proxy$a会在自己的方法里面调用真实的a的1方法(这拗口)。反正就是这么回事,那么我们来看看它的真实的应用空间:

事务控制,log还有什么??总之,这个特性还是不错的,但是实际上是不是还有别的替代方法呢??而且每当一个异常发生的时候面对着长长的堆栈,总让我有种想要骂娘的冲动。

让我们换个角度来想,如果我们不用spring会出现什么情况??没有spring我们需要手动在代码里面开关事务,好吧,我不想手动去做,所以我会把事务的处理代码抽象出来放到一个基础类里面,在任何需要使用事务的地方调用一下,然后呢?如果我想做的再多一点儿的话我会放弃调用基本的那种事务模型,我会自己实现一个context(应用程序上下文),在程序执行的过程中向上下文写入状态来自动决定是否启用事务,如果要求再高一点儿可以设计一个流程控制,每段function都需要绑定到该流程控制,任何一个function的失败将导致事务的回滚之类的,(当然了这些都需要根据实际情况自己去慢慢设计)。为什么我会感觉我的想法比spring略好呢?我感觉到了更低的代码侵入,更好理解的系统架构。好吧,对于AOP的讨论到此为止吧,我感觉这个功能能用,但是为了用这个功能而使用spring的话好像有什么地方不对(这个地方想好了再加吧。)



下面是关于代码管理和结构设计的几个想法:

首先代码应该层次分明,我所谓的层次分明不是指硬性的规定几个包是哪个层次,而是一种逻辑的分开,比如action层如果想要访问service层的话必须要调用一个Adapter来找到自己要访问的类,然后调用一个Executer来执行真正的操作,而不能直接引用到该类。service调用DAL亦然。

其次代码应该是模块化的,根据功能或者系统的分布,代码应该被组织成模块内可见,然后所有的模块被一个factory或者Adapter来管理,最终决定整个系统的调用关系。也就是说各个模块之间只有一个宏观范围的接口类来进行相应的分发和执行的操作。具体的实现全部隐藏在后面,对于别的模块的调用者而言完全是个黑盒。(当然有点儿过,接口还是应该暴漏出去的)。



==============无敌分割线===============先去吃午饭=====================

猜你喜欢

转载自dwbin.iteye.com/blog/1554013