启动Spring容器
Spring容器可以手动创建,但是在项目中通常建议使用配置文件,声明式地创建Spring容器。在Web中创建Spring容器有如下两种方式
>直接在web.xml文件中配置创建Spring容器
>利用第三方MVC框架的扩展点,创建Spring容器
通过web.xml创建容器的方法更常见,借助ServletContextListener使得Spring容器随Web应用启动而自动启动。
配置于web.xml
<!-- 使用ContextLoaderListener初始化Spring容器 -->
<context-param>
<!-- 声明配置文件 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<!-- 自动初始化Spring容器-->
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
Spring根据配置文件创建WebApplicationContext,并将其保存在Web应用的ServletContext中
Spring与Struts2的整合策略
Struts在MVC框架中作为核心控制器,在不整合Spring框架的情况下,通常Struts根据用户请求直接创建业务逻辑组件.
这种由控制器直接创建业务组件的策略是非常不好的
工厂模式应该是比上面更好的一种策略.如果系统采用Spring,则Spring成为最大的工厂.Spring负责创建和管理业务组件.只是创建了业务组件还是不够的,那控制器如何才能访问到业务组件呢?
为了让控制器访问到Spring中管理的业务组件,通常有以下策略
>Spring容器管理Action,并通过依赖注入为控制器注入业务组件
>利用Spring的自动装配,让Action自动从Spring中获取业务组件
让Spring管理控制器
上面我们提到了,要让Spring管理控制器,充分利用Spring的Ioc特点为控制器注入业务组件.
<struts>
<constant name="conststruts.devMode" value="true"/>
<constant name="struts.i18n.encoding" value="GBK"/>
<!-- 所有的Action定义都应该放在package下 -->
<package name="lee" extends="struts-default">
<!-- 定义处理用户请求的Action,该Action的class属性不是实际处理类
, 而是Spring容器中的Bean实例-->
<!-- 若在Struts中定义了实际的处理类,Struts将直接调用实际的处理类,Spring将不能为它注入ms -->
<action name="loginPro" class="loginAction">
<result name="error">error.jsp</result>
<result name="success">welcome.jsp</result>
</action>
<!-- 让用户直接访问该应用时列出所有视图页面 -->
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
struts.xml
从Struts配置文件我们可以发现,我们并未给loginPro指定一个实际的控制器,我们说明了需要有一个名字叫做loginAction的实例化对象来作为控制器.
<?xml version="1.0" encoding="GBK"?>
<!-- Spring配置文件的根元素,使用spring-beans-3.0.xsd语义约束 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- 定义一个业务逻辑组件,实现类为MyServiceImp -->
<bean id="myService"
class="org.app.service.impl.MyServiceImpl"/>
<!-- 让Spring管理的Action实例 -->
<bean id="loginAction" class="org.app.action.LoginAction"
scope="prototype">
<!-- 依赖注入业务逻辑组件 -->
<property name="ms" ref="myService"/>
</bean>
</beans>
applicationContext.xml
在这里我们才指明了loginAction的原型是什么,我们希望Spring根据这个原型创建控制器,并为控制器中注入名为ms的业务逻辑组件
public class LoginAction implements Action{
private String username;
private String password;
private String tip;
private MyService ms;
public void setMs(MyService ms) {
this.ms = ms;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTip() {
return this.tip;
}
public void setTip(String tip) {
this.tip = tip;
}
public MyService getMs() {
return this.ms;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
if(ms.valid(getUsername(), getPassword())){
setTip("成功整合");
return SUCCESS;
}
else{
return ERROR;
}
}
}
在控制器中需要注入业务逻辑组件,业务逻辑组件判断用户是否能合法登陆
使用自动装配
在这中策略下Action不是由Spring创建,Spring只是负责为控制注入业务逻辑组件
这种情况下的配置文件有微小的变化,struts.xml需要指明实际的控制器原型,以便Struts实例化控制器,applicationContext.xml中则只需要指明业务逻辑组件的实现类。
在实例化Action时自动装配业务逻辑组件.