说说项目架构整个变化过程吧

拿用户注册来举例:

数据库里面有一张User表

需要把注册信息存储到User表中

1.   最开始是两层架构

就是cliect   +  jsp    +   DB

就是在view里面直接操作数据库,就是在视图上建立数据库连接,然后把每个字段存储到数据库中

2.    加入Domain Model

     构造一个Entity类

cliect   +  jsp    +  Entity + DB

对Entity的管理交给Jsp

建立一个User类,view中先对User进行实例化,然后再进行存储

这一步没有什么意义

3.   加入管理层

cliect +  jsp  +  Entity + Service + DB

把对User的管理交给Service层

管理层,也就是业务逻辑层

4.    加入Hibernate

使用Hibernate对数据库进行操作

这种做法是在项目中引入了Hibernate

Hibernate的作用是把数据插入到数据库中。

但是,

如果要跨数据库呢

如果要把数据存储到Xml文件中或者网络上呢而不需要数据库呢

所以UserManage对User的存储就不能写死成了Hibernate或者JDBC或者xml

所以要引入DAO层

5.  加入DAO层

cliect +  jsp  + UserManage + UserManageImpl+  User+ +UserDAO + UserDAOimpl + DB

把对数据的存储操作抽象成一个接口,这个接口里面定义增删改查的方法,然后有不同的实现类,实现不同的存储方式

可以把业务逻辑类也抽象出来,不过这种做法并不多

6.    加入Struct

也就是引入MVC

Controller就是Struct的filter

Action先执行业务逻辑,然后根据配置的view在,返回结果

M是由两层构成的,bussinuiss layer和DAO layer

7.       加入spring

spring其实是贯穿于整个过程的

在抽象需要实例化的地方用spring的IOC

在各个业务处理的时候可以用spring的AOP

在这里面,UserManage拿userDAO的时候使用的是注入(必须给他一个实现类)

Action用UserManage的时候也是注入

所以

spring和struct2结合的主要地方是Action

实际上,spring是struct的一个插件

在struct的文档插件一节可以看到spring插件

所以,spring才是主导,struct向spring要需要的Action。(即要的时候向插件来要)

8.      配置

要加入spring

web.xml中要有监听器,在application启动的时候,找到bean所对应的xml的文件,并初始化所有的bean

   <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
<!-- default: /WEB-INF/applicationContext.xml -->
</listener>

默认寻找的路径是 WEB-INF/applicationContext.xml

如果改了路径或者改了名称,需要配置

    <context-param>
<param-name>contextConfigLocation</param-name>
<!-- <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value> -->
<param-value>classpath:beans.xml</param-value>
</context-param>

classpath 表示是在src文件夹下

*的意思是可能配置文件有多个,比如不同的业务配置不同的文件,这里一下子读进来

这样,在启动的时候就启动了spring容器

 Action和spring的关系可以有两种方式

1. Action交给spring容器管理

把Action配到spring中去

加入struct2-spring-plugin.jar包

然后找到相应的Action,加上@Compont和@Resource,这样就交给了spring管理

@Component("u")
@Scope("prototype")
public class UserAction extends ActionSupport implements ModelDriven { private UserManager userManager;
......

@Resource
       public void setUserManager(UserManager userManager) {
           this.userManager = userManager;
       }

}

   <package name="registration" extends="struts-default">
<action name="u" class="u">
<result name="success">/registerSuccess.jsp</result>
<result name="fail">/registerFail.jsp</result>
</action>
</package>

 这里面Action上的component值必须和struct.xml中的action的class相同

 同时还加上@Scope("prototype") 非单例模式

    action交给spring管理,spring的bean默认是单例模式,

    但是strct每次收到一个请求,都要建立一个ActionContext,ValueStack,Action,然后把action放进valuestack

    如果定义成单例显示不符

    但是如果在action中不涉及成员变量的读写操作,可以用单例,稍微提高点效率

struct2-spring-plugin.jar这个jar包里有一个文件struct-plugin.xml:

<struts>
<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" /> <!-- Make the Spring object factory the automatic default -->
<constant name="struts.objectFactory" value="spring" /> ....... </structs>

有一个name=spring的bean是一个springFactory

一般情况下,Struct需要一个Action的时候,会去找自己的StructFactory,但是在执行上面后,会去找spring拿,而springFactory会自动找到配置文件

比如struct中Action的name为User

它会根据这个名称到spring容器中找到name为User的bean

Struct启动时,读取文件de顺序

  • 1.Structs-default.xml
  • 2.Structs-plugh.xml
  • 3.structs.xml
  • 4.struct.properties
  • 5.web.xml

而spring启动是在web.xml中,也就是说应用启动时,spring容器就已经初始化了,当struct需要时,直接去容器中拿。

  2.Action由struct容器管理

这种做法是Action上什么也不用加,action对象的产生是放在struct容器中的,不由spring管理

public class UserAction extends ActionSupport implements ModelDriven {    

    private UserManager userManager;
.........
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
}
<struts>
<package name="registration" extends="struts-default">
<action name="u" class="com.bjsxt.registration.action.UserAction">
<result name="success">/registerSuccess.jsp</result>
<result name="fail">/registerFail.jsp</result>
</action>
</package>
</struts>

就是在Action上什么标记也不加,那么Action就会在struct容器里

但是service和DAO改加还是要加,还是要放在spring容器里面

那么在struct容器里产生的时候,会自动到spring容器里找需要注入的东西,当然由于什么标记都没加,就是ByName找的

那如果想匹配指定的name怎么办呢,就不需要写set方法了,直接在Action的属性上加

public class UserAction extends ActionSupport implements ModelDriven {

    @Resource(“u”);
private UserManager userManager;
.........
}

当然,第一种方法比较好测试

SSH架构的更多相关文章

  1. .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)

    .Net MVC  导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) [原文地址] 通过MVC控制器导出导入Excel文件(可用于java SSH架构)   public cl ...

  2. WebLogic使用SSH架构部署遇到org.hibernate.hql.internal.ast.HqlTok

    其实这个问题在以前就遇到过,当时解决了,但今天在部署一个测试轻应用的时候一直没有想起来,特此记录一下. 这个问题出现在使用WebLogic(我使用的是10.3.5版本)发布SSH架构的应用.在操作数据 ...

  3. SSH 架构

    这几天学习了 ssh 架构,中间出了好多错误,现在终于整理好了,就记录下来 ssh机构的框架构成,以及它们的作用 struts2 :这个框架主要用做控制处理的,其核心是 Contraller ,即 A ...

  4. SSH架构实现在线支付功能

    在线支付是指卖方与卖方通过因特网上的电子商务网站进行交易时,银行为其提供网上资金结算服务的一种业务,她为企业和个人提供了一个安全.快捷.方便的电子商务应用环境和网上资金结算工具,在线支付不仅帮助企业实 ...

  5. ssh架构简单解释和vo po解释

      Struts.spring.Hibernate在各层的作用 1)struts 负责 web层. ActionFormBean 接收网页中表单提交的数据,然后通过Action 进行处理,再Forwa ...

  6. SSH架构简单总结

    Struts.spring.Hibernate在各层的作用 1)struts 负责 web层.    ActionFormBean 接收网页中表单提交的数据,然后通过Action 进行处理,再Forw ...

  7. ssh架构之hibernate(五)hql语句狂练

    1.练习题 1.查询所有商品的名称[查询特定属性](只有一个参数的话可以使用List<String>接收数据)2.查询所有商品的名称和供应商[查询特定属性](多个参数可以使用List< ...

  8. ssh架构之hibernate(四)二级缓存

    二级缓存使用步骤: 1.拷贝jar包 2.配置Hibernate.cfg.xml文件 a.#开启二级缓存 hibernate.cache.use_second_level_cache=true b.# ...

  9. ssh架构之hibernate(三)关系映射

    1.单向多对一 1.映射文件配置 2.model: 测试 1.查询测试 执行顺序,先查询多方,在查询一方,一方采用延迟加载 注意:如果不使用一方的数据,就关闭session,报错,同延迟加载中的报错类 ...

随机推荐

  1. 字符串长度计算、截取、url参数获取、计算百分比、时间戳格式化

    1.中英混合文字字符截取 //中文长度截取计算,可取中英混合,个数向上取整,精确度1个英文字符误差,一个英文算一个字符,一个汉字算一个字符. //sub("中文zlsd",1) - ...

  2. 用javascript操作xml

    用javascript操作xml 可以使用标准DOM操作. IE创建XML MSXML2.0DOMDocument function createXMLDOM(){ var version = [ ' ...

  3. mysql中char与varchar的区别

    在建立数据库表结构的时候,为了给一个String类型的数据定义一个数据库的数据库类型,一般参考的都是char或者varchar,这两种选择有时候让人很纠结,今天想总结一下它们两者的区别,明确一下选择塔 ...

  4. laravel队列-让守护进程处理耗时任务

    待解决的问题 最近在做一个服务器集群管理的web项目,需要处理一些极其耗时的操作,比如磁盘格式化分区.对于这个需求,最开始的想法是,为了让节点上的rpc(远程过程调用) service端尽可能简单(简 ...

  5. php快递单号查询源码

    贴下记录下php查询快递单号的源码,能查询各种快递的快递单号记录,中通.圆通快递.顺丰快递等都不是问题.只需要在 爱快递(www.aikuaidi.cn)上面申请一个快递key即可,下面把源码分享下, ...

  6. activemq启动不起来,报错Address already in use: JVM_Bind

    之前莫名其妙的activemq怎么都启动不起来后来多方查询是因为widows 的ICS服务. 解决方案是,我的电脑上邮件,选择服务,然后在服务中找到Internet Connection Sharin ...

  7. 菜鸟Android之路(上)

    自己为什么要学android 本人作为应届毕业生,自己进入社会前做过好多梦,可是呢,现实还是打败了无邪!!面对社会的压力和残酷的竞争力自己如何生成下去??我自己对自己说:第一步 先养活自己,才能走好以 ...

  8. Matlab中Rand()函数用法

    一.理论准备 matlab函数randn:产生均值为0,方差 σ^2 = 1,标准差σ = 1的正态分布的随机数或矩阵的函数. 用法:Y = randn(n),返回一个n*n的随机项的矩阵.如果n不是 ...

  9. js 正则 非负整数

    Javascript 正则表达式 非负整数 /** * 正则判断非负整数 */ function testnum(ob){ var reg=/^[0-9]+?$/; //如果正则需要判断非负整数并带2 ...

  10. 搭建mongodb分片

    搭建mongodb分片 http://gong1208.iteye.com/blog/1622078 Sharding分片概念 这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在shardi ...