读书人

问个SSH加载顺序的有关问题

发布时间: 2012-12-14 10:33:07 作者: rapoo

问个SSH加载顺序的问题
如题 :s2sh框架

请问加载顺序如何

不要粘贴网上的回复,我已经搜索了很多

看的有点乱了

我目前了解到的

web.xml 读到 cont-param和listener

先contparam读取classpath下的 spring文件

然后加载listener,把 action 引入 bo 的 借口拿到?
这块有点不太清晰

然后又自动注入相关,我不大清楚顺序


问题:应用启动时 是先 spring 呢还是先struts

此外里面具体的不用详细说,我就想知道 各部分是怎么衔接的

还是,注入的时候

加入我在分了好多层 ,对用好多个 spring 配置文件

一层调用一层

请问 当我 出发一个请求时,是如何 在这 几个 app开头的xml文件里面找出对应项(注入)的呢

还是其他机制?这点老迷糊了

要是每次都查找,效率也太低了

所以肯定有什么我不理解的

望清晰的人作答,让 小弟一看就明白。

不太清楚的,望不要乱回答。


不胜感激
[最优解释]
嗯……应该是Spring解析xml的时候的检查问题。同一个文件内不允许相同的beanid,这是spring解析xml的检查机制。
两个文件具有相同的id的bean,那么spring会注入两次。是对相同对象连续注入两次,所以没有什么错误发生。

但是,这么弄很容易造成混淆。开发者很容易自己把自己给弄晕,改了其中一个而忘了改另一个。
假如两个文件具有相同id的bean,但注入内容有不同,那么最终内容是后面注入的那个,等于就是覆盖了。

你可以实验下,两个bean,使用相同的id和class,对同样的对象注入不同的内容。

这里涉及到spring载入配置文件顺序问题。
spring载入配置文件,如果你是指明了spring配置,按逗号隔开,那么按照你指定的先后顺序进行载入。
但假如是使用了通配符,那么是按照字母顺序载入的。
[其他解释]
最简单的方法 自己配置一个SSH框架 然后写一套方法看看怎么走的 ,spring就是一个容器,关键还是看web中加载struts.xml的过程,在到action的过程中有一些拦截器,他们负责调用action的set或者get方法给对应的属性注射值,还有当初我最迷糊的,用了hibernate之后,跟数据库就没有任何关系了,铭记!
[其他解释]
靠……这问题我还专门做过笔记的……算你运气好,免费分享给你……
当初可是费了我一番力气分析的
[其他解释]
先是Struts1.x 与Spring的结合配置使用流程:
该方案通过"自动注入"的方式获取对象,也即"依赖注入"方式。
较为常用,但特定情况下使用不了。如两个JVM,一个在长沙运行,一个在深圳运行,就不能同时实现注入,(1)"Spring和Struts的支持环境构建"
复制Struts、Spring相关包,并提供Struts、Spring的配置
提供国际化支持,提供缺省的国际化资源文件。
(2)"配置web.xml"
配置<context-param>,其中内容为Spring的配置文件applicationContext.xml。注意<param-name>的内容,必须为"contextConfigLocation";
配置<listener>,使用Spring提供的ContextLoaderListener。
配置范例:


<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

解析:
当Web应用启动时,将执行以下操作:
①由Tomcat创建一个ServletContext,并自动载入<context-param>中的属性;
②ContextLoaderListener检测到ServletContext的创建,运行Spring的相关程序;
③Spring根据<context-param>中contextConfigLocation的指向,加载对应applicationContext.xml;
④Spring根据applicationContext.xml的内容创建一个BeanFactory实例,并放入ServletContext中。
简而言之,该配置的作用是:当Web应用启动时,Spring将自动创建一个BeanFactory实例,并放入ServletContext中。
(3)"配置Struts"
struts-config.xml文件中,注意其<action>标签的type属性,设置为Spring的代理Action类。由此真正的action创建交给Spring完成。
若不使用Spring,type设置为com.project.LoginAction等自定义类;使用Spring,type设置为"org.springframework.web.struts.DelegatingActionProxy"。
但"仍需构建具体Action",并编写Action的具体方法。该Action"在Spring的配置中引用",详见"(4)配置Spring"。
相当于将Struts配置转移到了Spring配置中,此处即Struts与Spring框架结合的关键结合点。
配置范例:

<struts-config>
<form-beans>
<form-bean name="loginForm" type="com.project.usermgr.web.forms.LoginActionForm"/>
</form-beans>
<action-mappings>
<action path="/login"
type="org.springframework.web.struts.DelegatingActionProxy"
name="loginForm"
scope="request"
>
<forward name="success" path="/login_success.jsp"/>
</action>
</action-mappings>


<message-resources parameter="MessageResources" />
</struts-config>


(4)"配置Spring"
由Spring来创建和管理Action,并向Action注入Model层Service对象。
设置scope="prototype"后可使每个线程都有一个新的Action,从而解决Struts1.x的Action线程安全问题。
注意:
①必须使用name属性,且name属性的值必须和struts-config.xml文件中<action>标签的path属性值一致
②必须配置Model层Service对象,如userManager等。
配置范例:

applicationContext-beans.xml:
<bean name="/login" class="com.project.usermgr.web.actions.LoginAction" scope="prototype">
<property name="userManager" ref="userManager"/>
</bean>

(5)"构建Action"
Model层Service对象由Spring"自动注入",因此无需手动构建该对象,也无需获取BeanFactory。通过"自动注入"的方式获取对象,即"依赖注入"。
注意,相关对象须提供set方法,以方便Spring注入。

public class LoginAction extends Action {
private UserManager userManager;
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
LoginActionForm laf = (LoginActionForm)form;
String username = laf.getUsername();
String password = laf.getPassword();
userManager.login(username, password);
return mapping.findForward("success");
}
//须提供set方法,以方便Spring注入。
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
}

[其他解释]
页面->SERVLET容器配置转发->STRUTS2捕获请求->SPRING业务处理(包括事物)->HIBERNATE处理数据->返回业务处理->返回STRUTS2->页面
[其他解释]
Struts2与Spring的结合就很简单了。
注意Struts2在web.xml中的配置:

<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/ *</url-pattern>
</filter-mapping>

Struts2用的是一个filter。只有在用到action的时候,才会读取Struts2的配置,明显Spring先启动。


楼主的问题,问到Spring的构建机制和注入机制,其实很简单。
Spring由listener启动之后,读取Spring的配置文件applicationContext.xml。如有多个配置文件,会全部读取。注意,是“全部”读取,不管有多少个。
Spring的配置文件中,基本都是<bean>,一个bean对应一个对象。Spring在读取配置完毕后,就立刻实例化这些对象。所以,这些对象是很早就被实例化好了的,并被保存起来。当程序需要使用这些对象时,则直接从内存中获取。Spring会把这些实例好了的对象保存在一个map里,第一次用的时候从map里取,查找速度是很快的。且查找一次之后,程序使用的就是引用了。

这里要稍微注意的就是scope="prototype"的情况。
①scope="singleton",默认值。顾名思义,单例。
②scope="prototype",每次都会生成新的实例,从IoC容器中获得的对象每次都是"不同"的。
若使用非线程安全的类,可以考虑使用prototype。

同其他对象一样,prototype在一开始也会被实例化一个对象出来。当此对象被使用后,Spring将额外再生成一个对象放到map里,供其他线程使用。

此外,Spring还有AOP机制。AOP说白了就是代理。一种是java的动态代理,还有一种则是CGLIB的继承式代理。这些代理类,与那些ioc容器的对象一样,也都是在Spring配置读取完成之后立刻被创建的。

Spring配置中的东西,都是一开始就被创建好了的,根本就不存在“重复查找”的问题。
[其他解释]
看到个帖子,从Spring的源代码的角度分析了Spring的运行机制:
http://graykeel.iteye.com/blog/696984

摘抄结语部分的内容如下:

整个bean的生成过程:
1:生成xml格式的配置文件
2:通过ResourceLoader将配置文件读入
3:通过BeanDefinitionReader将配置信息转换程BeanDefinition
4:在通过BeanFactory根据BeanDefinition信息创建bean实例
5:将bean实例放入SingletonBeanRegistry中以供使用
[其他解释]
今天真是幸运啊,非常感谢兄弟的精彩回答。不胜感激。一目了然啊。今天是我幸运的一天啊。

我的理解看看对不对

总是不管spring 用何种方式 ,把 bean 都实例化了

不管他们的顺序,总之 都 放好了



至于Action层,加上那个listener,action引用的 bo层的类 ,也 注入到 action
里面了

然后struts 负责 请求 ,请求来了 ,就进action ,里面注入的类 有了 拿来用

也可能有没注入的 ,管它呢,执行就行了 、
[其他解释]

引用:
今天真是幸运啊,非常感谢兄弟的精彩回答。不胜感激。一目了然啊。今天是我幸运的一天啊。

我的理解看看对不对

总是不管spring 用何种方式 ,把 bean 都实例化了

不管他们的顺序,总之 都 放好了

至于Action层,加上那个listener,action引用的 bo层的类 ,也 注入到 action
里面了

然后struts 负……




再说下……对象注入,只要配置正确,是绝对会被注入成功的。没注入成功,必然会报错。比如bean的名字写错,或者目标对象不存在等等。

另外,zhaolibin147兄弟也说得对。Struts2也涉及到注入属性。但Struts2的属性注入,是在访问Action的时候才执行的。
拦截器就相当于若干个Filter,其中有几个拦截器负责注入属性。所以Struts的属性注入时间比较晚。
而且由于Action是每个线程都会生成实例,所以属性都是随着Action的生成而被注入的。
简单来说,Struts2中被注入的属性,比如request、session,这些对象是在客户发起访问后、action创建前被注入的。
[其他解释]
恩谢谢补充,不过我又发现一个问题

如果在同一个app_xx。xml时,写 两个 一样的 bean ,就是id相同,就是会出错

但是如果,在两个xml文件里面,写上同样的bean id 里面的属性都一样,

不会报错,启动也不会报错

我登陆简单测试了一下,也没感觉 有错误

那这时 会建立两个 bean id相同的 ?
[其他解释]
谢谢兄弟,你的回答很精彩。

读书人网 >J2EE开发

热点推荐