`
hudeyong926
  • 浏览: 2018274 次
  • 来自: 武汉
社区版块
存档分类
最新评论

ssh整合

    博客分类:
  • JAVA
阅读更多

一.为什么要用框架和模式
1.为什么要用模式?
  因为模式是一种指导,在一个良好的指导下,有助于你完成任务,有助于你作出一个优良的设计方案,达到事半功倍的效果。而且会得到解决问题的最佳办法。
2.为什么要用框架?
  因为软件系统发展到今天已经很复杂了,特别是服务器端软件,设计到的知识,内容,问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。而且框架一般是成熟,稳健的,他可以处理系统很多细节问题,比如,事物处理,安全性,数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。总之:就是让开发更简单,让我们成功。
业务逻辑层:Spring IoC,降低耦合度,减少模块之间在开发的影响.技巧:面向接口编程,使用反射机制,hibernate粒度等。
持久层:spirng的Hibernate支持
查看开源框架jar包源码方法:F3/Attach Source/External Folder/选择开源框架的src目录或src文件。如C:\Program Files\Java\jdk1.6.0_02\src.zip
                struts+spring方案一
原理:在Action中获取BeanFactory,并通过BeanFactory对象获取业务逻辑对象。
1创建web应用
2spring和struts集成
   安装struts{
struts的jar包
修改web.xml文件,定义struts的ActionServlet
提供struts-config.xml文件
提供国际化资源文件}
安装spring
拷贝spring的jar包
提供spring的配置文件
3在struts的Action中调用如下代码取出BeanFactory
     BeanFactory factory=WebApplicationContextUtils
                         .getRequiredWebApplicationContext(servletContext);
4通过BeanFactory取得业务对象,调用业务逻辑方法(不管理action)
struts+spring方案二
(耦合度比方案一低,最大的不便是所有的Action 必须同时在Struts 和
Spring 的配置文件中各配置一次。)
原理:将业务逻辑对象通过spring注入到action中,从而避免了在action中直接代码查找。
3因为Action中需要调用业务逻辑,在action中提供setter方法,让spring将业务逻辑对象注入给我们
4struts-config.xml文件中的<action>标签要改
5spring配置
local属性是在同一个配置文件中的bean
bean属性是指出一个bean,可以不在同一个配置文件中
一般用get不用load,因为get没有值返回null,而load会抛异常
spring需要配置hibernate的懒加载能够让Session解释完成再关闭,避免懒加载异常。OpenSessionInViewFilter模式web.xml中加入
<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
window/show view/springbeans
show In spring beans view看spring bean的属性,看bean直接的依赖关联情况:在springbeans工作区里右键.xml文件/show Graph.
创建 Spring 配置文件,将文件放到src目录下,文件名称为 applicationContext.xml, 编译后放到 WEB-INF/classes/ 下.配置struts-config.xml文件,添加 spring的插件, 位置在 struts-config 文件的<message-resources>标签末尾.
<!-- 加载spring,xml -->
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
    <set-property    property="contextConfigLocation"    value="WEB-INF/classes/applicationContext-action.xml,WEB-INF/classes/applicationContext-business.xml,WEB-INF/classes/applicationContext-dao.xml,WEB-INF/classes/applicationContext-pojos.xml,WEB-INF/classes/applicationContext-sessionFactory.xml" />
  </plug-in>
<!--action注入service、pojo,service注入dao,dao注入sessionFactory-->
方法二:web.xml中加入
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            WEB-INF/applicationContext-*xml,classpath*:/applicationContext-*xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
3. 修改 Struts 的 struts-config.xml 中的Action配置
原:
<action
attribute="loginForm"
input="/login.jsp"
name="loginForm"
path="/login"
scope="request"
validate="true"
type="com.test.struts.action.LoginAction" />
改为:
<action
attribute="loginForm"
input="/login.jsp"
name="loginForm"
path="/login"
scope="request"
validate="true"
type="org.springframework.web.struts.DelegatingActionProxy" />
type 部份为修改内容, 这里将使用spring的代理器来对Action进行控制. 没有调用到dao的Action的type没有必要改代理类来截获,
当提交到/login.do是将控制权交给了spring,然后由spring来把它转回到struts的Action.
修改 Struts 的 struts-config.xml 中的Action配置方法二
在<message-resources>标签前添加
<controller>
  <set-property property="processorClass"
      value="org.springframework.web.struts.DelegatingRequestProcessor"/>
</controller>
增加这些设置之后,不管你查询任何类型的 Action,Sping都自动在它的context配置文件中寻找。实际上,你甚至不需要指定类型。下面两个代码片断都可以工作:
<action path="/user" type="com.whatever.struts.UserAction"/>       
<action path="/user"/>
如果你使用 Struts 的 modules 特性,你的 bean 命名必须含有 module 的前缀。 举个例子,如果一个 Action 的定义为 <action path="/user"/>,而且它的 module 前缀为“admin”, 那么它应该对应名为 <bean name="/admin/user"/> 的 bean。注意:
action bean必须使用name属性,不能用id属性
那么属性必须和struts-config.xml中的<action>标签的path属性值一致
最好将scope设置为prototype(或singleton=false),即每次请求创建一个action,从而避免了struts action的线程安全
4. 配置spring 来实例化被删除的 Action type.
<beans>
<bean name="/login" class="com.test.struts.action.LoginAction" scope=prototype></bean>
</beans>
Spring 通过 org.springframework.web.struts.DelegatingActionProxy 这个类, 然后根据 Struts 配置文件中的 <action path="/login" ..> 和 Spring 配置文件中的 <bean name="/login" ..> 来将 Spring 管理下的 Struts Action 类和提交的路径匹配起来, 这些就是关于转交控制权的配置内容.

hibernate.cfg.xml中
当没有数据库表时可以在hibernate.cfg.xml中配置,让他运行时自己建表
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>  <!--终端输出sql-->
<property name="format_sql">true</property>
<!-- 使SQL语句格式更加美观统一 -->

<property name=" use_sql_comments ">true</property> <!--添加sql注释-->
<property name="connection.useUnicode">true</property>
<property name="connection.characterEncoding">UTF-8</property>
spring.xml中
<prop key="show_sql">true</prop>
<prop key="format_sql">true</prop>
<prop key="connection.useUnicode">true</prop>
<prop key="connection.characterEncoding">UTF-8</prop>

Middlegen+Ant+XDoclet能很方便构建项目.配置环境变量可以使用或方便使用因为可以命令行直接输入命令,不需要到该目录下。
spring事务管理
getHibernateTemplate().executeFind()返回list。
静态方法不能用getHibernateTemplate()因此可以用HibernateTemplate。HibernateTemplate对Hibernate Session操作进行了封装,借助HibernateTemplate我们可以脱离每次数据操作必须首先获得Session实例、启动事务、提交/回滚事务以及烦杂的try/catch/finally的繁琐操作。
    <bean id="hibernateTemplate"
        class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </proper
</bean>
JDK 的代理机制来实现事务管理的解决方案, 相比起来它有一个麻烦的地方就是必须需要生成一个 DAO 的接口才能工作. 那么另一种比较简单的解决方案就是用 CGBLIB, 可以不用编写接口, 那么下面是 Spring 参考文档中的内容:
基于JDK和CGLIB的代理
这个小节作为说明性文档,解释了对于一个目标对象(需要被代理的对象),ProxyFactryBean是如何决定究竟创建一个基于JDK还是CGLIB的代理的。
注意
ProxyFactoryBean需要创建基于JDK还是CGLIB代理的具体行为在版本1.2.x和2.0中有所不同。现在ProxyFactoryBean在关于自动检测接口方面使用了与TransactionProxyFactoryBean相似的语义。
如果一个需要被代理的目标对象的类(后面将简单地称它为目标类)没有实现任何接口,那么一个基于CGLIB的代理将被创建。这是最简单的场景,因为JDK代理是基于接口的,没有接口意味着没有使用JDK进行代理的可能。 在目标bean里将被插入探测代码,通过interceptorNames属性给出了拦截器的列表。注意一个基于CGLIB的代理将被创建即使ProxyFactoryBean的proxyTargetClass属性被设置为false。 (很明显这种情况下对这个属性进行设置是没有意义的,最好把它从bean的定义中移除,因为虽然这只是个多余的属性,但在许多情况下会引起混淆。)
如果目标类实现了一个(或者更多)接口,那么创建代理的类型将根据ProxyFactoryBean的配置来决定。
如果ProxyFactoryBean的proxyTargetClass属性被设为true,那么一个基于CGLIB的代理将创建。这样的规定是有意义的,遵循了最小惊讶法则(保证了设定的一致性)。 甚至当ProxyFactoryBean的proxyInterfaces属性被设置为一个或者多个全限定接口名,而proxyTargetClass属性被设置为true仍然将实际使用基于CGLIB的代理。
如果ProxyFactoryBean的proxyInterfaces属性被设置为一个或者多个全限定接口名,一个基于JDK的代理将被创建。被创建的代理将实现所有在proxyInterfaces属性里被说明的接口;如果目标类实现了全部在proxyInterfaces属性里说明的接口以及一些额外接口,返回的代理将只实现说明的接口而不会实现那些额外接口。
如果ProxyFactoryBean的proxyInterfaces属性没有被设置,但是目标类实现了一个(或者更多)接口,那么ProxyFactoryBean将自动检测到这个目标类已经实现了至少一个接口, 一个基于JDK的代理将被创建。被实际代理的接口将是目标类所实现的全部接口;实际上,这和在proxyInterfaces属性中列出目标类实现的每个接口的情况是一样的。然而,这将显著地减少工作量以及输入错误的可能性。
好了, 详细阐述这个解决方案.
用 MyEclipse 的自动生成功能产生的 Spring + Hibernate 的 DAO 有时候会出现不能保存数据但是可以查询数据的问题, 这是因为默认生成的 Spring 配置文件里面没有包含对事务的操作, 也就是没有 commit Hibernate transaction 的调用所以无法保存数据. 也就是正确的调用需要 beginTran, save, commit, 但是现在就少了 tran 的调用代码部分.
解决方法是在配置文件里"侵入性"(必须这样做, 做额外的配置和修改, 否则就无法正常工作, 所以是侵入性的)的加入事务配置后就可以正常的保存数据了.
1. 用 Eclipse 的重构给自动生成的 UsersDAO 类添加一个接口, 里面包含所有的方法声明, 例如 IUsersDAO, 加入接口的目的是为了使用 JDK 的动态代理方式实现的 Spring AOP 来工作,
2. 修改配置文件给原来的 UsersDAO 加入代理类来进行事务管理:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
.................
    <!-- UsersDAO implements IUsersDAO 接口 -->
    <bean id="UsersDAO" class="dao.UsersDAO">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
................
1.基于CGLIB的代理, 修改配置文件给原来的 UsersDAO 加入代理类来进行事务管理:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!--右键new sessionFactory-->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation"
            value="file:src/hibernate.cfg.xml">
        </property>
    </bean>
    <bean id="UsersDAO" class="dao.UsersDAO">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
<!-- 以下两个 Bean transactionManager 和baseTxProxy 是新加入的内容, 用来配置事务 -->
    <!-- 声明一个 Hibernate 3 的 事务管理器供代理类自动管理事务用 -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
    <!-- 这个代理类是最后对外公开的类, 否则因为没有进行事务操作,
    保存时没有提交 hibernate 的事务, 这将无法对数据库进行改动, 也就是原来要调用 UsersDAO 的地方都要转而调用这个代理对象 baseTxProxy; 具体的属性配置在 target 参数那里指定了这个对象对原来的 UsersDAO 对象进行代理;
    也因为要使用代理, 只有通过它来作为原来配置的UsersDAO 的代理工作, 才能让 Spring 在保存数据的时候自动打开Hibernate 的Transaction 并提交, 即属性 transactionManager 配置的 HibernateTransactionManager --> 
  <bean id="baseTxProxy" lazy-init="true" 
  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager"><ref bean="transactionManager"/></property>
<!-- 注意这个属性,  必须为 true 使用CGLIB才不用强制编写DAO接口,使用dao接口不需要-->
        <property name="proxyTargetClass">
            <value>true</value>
        </property>
  <property name="target">
  <ref local="userServiceTarget " />
  </property>
  <property name="transactionAttributes">
  <props>
  <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
  <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
  <prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>
  <prop key="*">PROPAGATION_REQUIRED</prop>
<!-- *是通配符,可以表示没有注册的所有方法 -->
  </props>
  </property>
  </bean>
  <bean id="userServiceTarget" class="org.mzone.service.impl.userServiceTarget">
        <property name="userDAO"><ref local="userDAO"/></property>
         <property name="articleDao"><ref local="articleDAO"/></property>
  </bean>
</beans>

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics