首先强调的一点是我不是反对使用Spring,而是反对滥用Spring。
恕我孤陋寡闻,据我目前看到的情况,Spring的特性主要应用于两个地方:业务层和DAO层。业务层真正需要注入的绝大多数是持久化对象或者DAO,以控制其事务;DAO层主要是为了实现“面向接口编程”的理念。就这两个问题简单的分析一下。
如果只是需要进行事务控制而采用Spring是大可不必的,统一控制事务的方式很多,也比较简单,如果单单是为了这个目的使用Spring,维护一大堆的配置文件,我的感觉是得不偿失。除非不把我们的开发和维护时间计算成本。
另一个问题,所谓的“面向接口编程”有过度工程之嫌。在我们可预见的将来,我们能够利用上这些可扩展性么?我们有多少可能将持久化的机制由Hibernate转换到EJB呢?我们为了可扩展性付出的代价是否值得?看一下我们的配置文件,是不是都是相近或者雷同的编码呢?我们维护的这些配置文件是否值得么?
比维护的问题更重要的问题体现在,这些框架的组合(很少看到单独使用Spring的情况,多是Struts、Spring和Hibernate的组合)提高了开发的门槛,使得刚入门的人不能顺利地完成一个很简单的开发。也就是说,学习曲线过于陡峭。就目前的国内情况来看,多数的情况下(80/20原则)的应用开发(企业应用)无非是简单的增删查改而已,让程序员们都了解和熟悉怎么注入和依赖的是否有些过于牵强呢?
典型情况下,我们需要维护的类有如下一些:Service、IService、IDao、Dao、POJO、Spring配置文件(可能还有Hibernate的hbm文件)等这些文件,维护量之大可想而知,这里还不包括Struts相关的文件(Action、Form、配置文件、校验文件、数个JSP文件)。真是一个维护的恶梦呀!
下面是一个典型的Spring的配置文件,是否似曾相识呢?
<beans>
<!-- ========================= Start of PERSISTENCE DEFINITIONS ========================= -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>java:comp/env/ds</value></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/aaa/sys/po/hibernate/AAA.hbm.xml</value>
<!-- 此处删除200行 -->
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.c3p0.min_size">20</prop>
<prop key="hibernate.c3p0.max_size">50</prop>
<prop key="hibernate.c3p0.timeout">5000</prop>
<prop key="hibernate.c3p0.max_statements">100</prop>
<prop key="hibernate.c3p0.idle_test_period">3000</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean
id="xxxDao"
class="com.xxx.yyy.dao.hibernate.xxxDao"
>
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
</bean>
<!-- 此处删除1000行 -->
<bean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean
id="aaaService"
parent="txProxyTemplate">
<property name="target">
<bean class="com.aaa.bbb.service.AAAService" >
<property name="xxxDao">
<ref bean="xxxDao"/>
</property>
</bean>
</property>
</bean>
<!-- 此处删除3000行 -->
</beans>
我的观点是:1. 在必要的时候设计精巧的结构或者接口,而不是搞大多无用的接口。2. 对于程序员来说,应该尽量采用“可使由之,不可使知之”的策略。即使是我自己编写业务逻辑的时候,我也不想关心是否关闭了数据库连接。
恕我孤陋寡闻,据我目前看到的情况,Spring的特性主要应用于两个地方:业务层和DAO层。业务层真正需要注入的绝大多数是持久化对象或者DAO,以控制其事务;DAO层主要是为了实现“面向接口编程”的理念。就这两个问题简单的分析一下。
如果只是需要进行事务控制而采用Spring是大可不必的,统一控制事务的方式很多,也比较简单,如果单单是为了这个目的使用Spring,维护一大堆的配置文件,我的感觉是得不偿失。除非不把我们的开发和维护时间计算成本。
另一个问题,所谓的“面向接口编程”有过度工程之嫌。在我们可预见的将来,我们能够利用上这些可扩展性么?我们有多少可能将持久化的机制由Hibernate转换到EJB呢?我们为了可扩展性付出的代价是否值得?看一下我们的配置文件,是不是都是相近或者雷同的编码呢?我们维护的这些配置文件是否值得么?
比维护的问题更重要的问题体现在,这些框架的组合(很少看到单独使用Spring的情况,多是Struts、Spring和Hibernate的组合)提高了开发的门槛,使得刚入门的人不能顺利地完成一个很简单的开发。也就是说,学习曲线过于陡峭。就目前的国内情况来看,多数的情况下(80/20原则)的应用开发(企业应用)无非是简单的增删查改而已,让程序员们都了解和熟悉怎么注入和依赖的是否有些过于牵强呢?
典型情况下,我们需要维护的类有如下一些:Service、IService、IDao、Dao、POJO、Spring配置文件(可能还有Hibernate的hbm文件)等这些文件,维护量之大可想而知,这里还不包括Struts相关的文件(Action、Form、配置文件、校验文件、数个JSP文件)。真是一个维护的恶梦呀!
下面是一个典型的Spring的配置文件,是否似曾相识呢?
<beans>
<!-- ========================= Start of PERSISTENCE DEFINITIONS ========================= -->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>java:comp/env/ds</value></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/aaa/sys/po/hibernate/AAA.hbm.xml</value>
<!-- 此处删除200行 -->
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.Oracle9Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.c3p0.min_size">20</prop>
<prop key="hibernate.c3p0.max_size">50</prop>
<prop key="hibernate.c3p0.timeout">5000</prop>
<prop key="hibernate.c3p0.max_statements">100</prop>
<prop key="hibernate.c3p0.idle_test_period">3000</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean
id="xxxDao"
class="com.xxx.yyy.dao.hibernate.xxxDao"
>
<property name="jdbcTemplate">
<ref bean="jdbcTemplate"/>
</property>
</bean>
<!-- 此处删除1000行 -->
<bean id="txProxyTemplate" abstract="true"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean
id="aaaService"
parent="txProxyTemplate">
<property name="target">
<bean class="com.aaa.bbb.service.AAAService" >
<property name="xxxDao">
<ref bean="xxxDao"/>
</property>
</bean>
</property>
</bean>
<!-- 此处删除3000行 -->
</beans>
我的观点是:1. 在必要的时候设计精巧的结构或者接口,而不是搞大多无用的接口。2. 对于程序员来说,应该尽量采用“可使由之,不可使知之”的策略。即使是我自己编写业务逻辑的时候,我也不想关心是否关闭了数据库连接。