| Spring Framework从诞生之日起,受到了越来越多的关注。最近,新的开源项目大多支持Spring Framework。国内目前也有专门的网站(http://spring.jactiongroup.net/)。那它为什么如此受欢迎呢? 我想最重要的是,EJB让每个人都痛恨。要编写一个EJB,需要写LocalHome, RemoteHome, Bean, LocalInterface, RemoteInterface,需要一个标准描述符,一个特殊厂商描述符(Weblogic、WebSphere都不一样),如果是Entity Bean,还需要Mapping文件。如此之多,实在麻烦。但EJB最重要的是解决Transaction问题,没有Spring之前,没有其他方法能够描述式的解决它。每个人、每个公司为了解决Transaction的问题,编程的写法都不一样,百花齐放。于是,在最需要它的时候,Spring出现了。 Spring的功能非常多。但对于一个产品,最重要的是如何用好它的精华。Spring包含AOP、ORM、DAO、Context、Web、MVC几个部分组成。Web、MVC暂不用考虑,用成熟的Struts、JSP或Webwork更好。DAO由于目前Hibernate、JDO的流行,也可不考虑。因此最需要用的是AOP、ORM、Context。 Context中,最重要的是Beanfactory,它是将接口与实现分开,非常重要。以前我们写程序,如一个接口IDocument,一个实现类Document1。在写程序时,需写成IDocument doc = new Document1(),一旦我们的实现类需改变时,变为Document2,则程序需写成IDocument doc = new Document2(),所有用到的地方全需改。Beanfactory帮我们解决了这个问题,用context后,写法变为IDocument doc=(IDocument)beanFactory.getBean("doc")。如果实现类从Document1改为Document2,直接在配置文件改就可以了。Context是Bean factory的进一步抽象。很多人都喜欢用ApplicationConext,用Servlet把它Load。这样就把Bean Factory与Web绑定在一起。如果是Fat Client或Remote调用,则这些Bean factory就很难调用,实际是将表现层与业务层绑定的太紧。推荐的方法是SingletonBeanFactoryLocator。具体为:    BeanFactoryLocator bfLocator = SingletonBeanFactoryLocator.getInstance();BeanFactoryReference bf = bfLocator.useBeanFactory("beanFactory");
 // now use some bean from factory
 return bf.getFactory().getBean(name);
    <beans>      <bean id="beanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext"><constructor-arg>
 <list>
 <value>dataAccessContext.xml</value>
 <value>securityContext.xml</value>
 <value>...</value>
 </list>
 </constructor-arg>
 </bean>
 </beans> 这样,就可随时动态扩展,实现组件式的开发。
 Spring Framework最得以出名的是与Hibernate的无缝链接,基本上用Spring,就会用Hibernate。可惜的是Spring提供的HibernateTemplate功能显得不够,使用起来也不是很方便。我们编程序时,一般先写BusinessService,由BusinessService调DAO来执行存储,在这方面Spring没有很好的例子,造成真正想用好它,并不容易。 我们的思路是先写一个BaseDao,仿照HibernateTemplate,将基本功能全部实现: public class BaseDao extends HibernateDaoSupport{     private Log log = LogFactory.getLog(getClass());     public Session openSession() {return SessionFactoryUtils.getSession(getSessionFactory(), false);
 }
     public Object get(Class entityClass, Serializable id) throws DataAccessException {Session session = openSession();
 try {
 return session.get(entityClass, id);
 }
 catch (HibernateException ex) {
 throw SessionFactoryUtils.convertHibernateAccessException(ex);
 }
 }
     public Serializable create(Object entity) throws DataAccessException {Session session = openSession();
 try {
 return session.save(entity);
 }
 catch (HibernateException ex) {
 throw SessionFactoryUtils.convertHibernateAccessException(ex);
 }
 }
 ... 其它的DAO,从BaseDao继承出来,这样写其他的DAO,代码就会很少。 从BaseDao继承出来EntityDao,专门负责一般实体的基本操作,会更方便。 public interface EntityDao {     public Object get(Class entityClass, Serializable id) throws DataAccessException;     public Object load(Class entityClass, Serializable id) throws DataAccessException;     public Serializable create(Object entity) throws DataAccessException;...}
 /*** Base class for Hibernate DAOs.  This class defines common CRUD methods for
 * child classes to inherit. User Sping AOP Inteceptor
 */
 public class EntityDaoImpl extends BaseDao implements EntityDao{
 } 为了Transaction的控制,采用AOP的方式: public interface EntityManager {     public Object get(Class entityClass, Serializable id);     public Object load(Class entityClass, Serializable id);     public Serializable create(Object entity);...
 } /*** Base class for Entity Service. User Sping AOP Inteceptor
 */
 public class EntityManagerImpl implements EntityManager {
     private EntityDao entityDao;     public void setEntityDao(EntityDao entityDao) {this.entityDao = entityDao;
 }
     public Object get(Class entityClass, Serializable id) {return entityDao.get(entityClass, id);
 }
     public Object load(Class entityClass, Serializable id) {return entityDao.load(entityClass, id);
 }
 ...
 } 这样我们就有了一个通用的Hibernate实体引擎,可以对任何Hibernate实体实现基本的增加、修改、删除、查询等。 其它的BusinessService就可以继承EntityManager,快速实现业务逻辑。 具体XML配置如下:  <!-- Oracle JNDI DataSource for J2EE environments --><bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
 <property name="jndiName"><value>java:comp/env/jdbc/testPool</value></property>
 </bean>
  <!-- Hibernate SessionFactory for Oracle --><!-- Choose the dialect that matches your "dataSource" definition -->
 <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
 <property name="dataSource"><ref local="dataSource"/></property>
 <property name="mappingResources">
 <value>user-hbm.xml</value>
 </property>
 <property name="hibernateProperties">
 <props>
 <prop key="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</prop>
 <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.Provider</prop>
 <prop key="hibernate.cache.use_query_cache">true</prop>
 <prop key="hibernate.show_sql">false</prop>
 </props>
 </property>
 </bean>
  <!-- AOP DAO Intecepter --><bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
 <property name="sessionFactory">
 <ref bean="sessionFactory"/>
 </property>
 </bean>
         <bean id="entityDaoTarget" class="com.gpower.services.entity.dao.EntityDaoImpl"><property name="sessionFactory">
 <ref bean="sessionFactory"/>
 </property>
 </bean>
         <bean id="entityDao" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="proxyInterfaces">
 <value>com.gpower.services.entity.dao.EntityDao</value>
 </property>
 <property name="interceptorNames">
 <list>
 <value>hibernateInterceptor</value>
 <value>entityDaoTarget</value>
 </list>
 </property>
 </bean>
  <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --><bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
 <property name="sessionFactory"><ref local="sessionFactory"/></property>
 </bean>
  <!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) --><!--
 <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
 -->
  <!-- Transactional proxy for the Application primary business object --><bean id="entityManagerTarget" class="com.gpower.services.entity.EntityManagerImpl">
 <property name="entityDao">
 <ref bean="entityDao"/>
 </property>
 </bean>
         <bean id="entityManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionManager">
 <ref bean="transactionManager"/>
 </property>
 <property name="target">
 <ref bean="entityManagerTarget"/>
 </property>
 <property name="transactionAttributes">
 <props>
 <prop key="get*">PROPAGATION_SUPPORTS</prop>
 <prop key="*">PROPAGATION_REQUIRED</prop>
 </props>
 </property>
 </bean>
 资源:Spring+Hibernate培训ppt          |