struts2与spring集成时,关于class属性及成员bean自动注入的问题
正常来说按照Spring官方配置,在struts2与spring整合时,struts配置文件中class属性指向spring配置的bean id,但是在class指向类路径时,依然能注入service。
public class LoginAction extends ActionSupport{ private LoginService loginService; public void setLoginService(LoginService loginService) { System.out.println("init Service......"); this.loginService = loginService; }
spring配置
<bean id="loginService" class="org.xxxxx.services.impl.LoginServiceImpl"></bean> <bean id="loginAction" class="org.xxxxx.action.LoginAction"> </bean>
struts配置
<action name="login" class="org.xxxxx.action.LoginAction">
<result name="success">/result.jsp</result>
<result name="error">/login.jsp</result>
</action>
1.注意看以上两个红线部分,在struts.xml中action指定的class像上面这种方式指定全类路径名的话,这时,不论spring配置文件中的<bean id="loginAction" class="org.xxxxx.action.LoginAction"></bean>有没有指定配置<property name="loginService" ref="loginService",只要有<bean id="loginService" .../>存在,并且这个ID的名字与Action中成员bean的名字一致,当实例化Action类时,会一并将loginService的实例注入。
并且还存在一个问题当struts.xml此种方式配置时,spring中如果配置了此action实例,并添加scope=“prototype”多例属性,则会在访问时报错。可能struts2本身是多例与spring实例化机制冲突。所以此种方式配置时,可废弃spring中的action类配置。
2.如果<action name="login" class="loginAction">这里的class指定spring配置文件中的bean的id,则不会出现loginService自动注入问题,而是根据<bean id="loginAction" class="org.xxxxx.action.LoginAction"></bean>有没有指定配置<property name="loginService" ref="loginService"/>来决定,有<property name="loginService" ref="loginService"/>的指定,则实例化Action类时,会一并将loginService实例注入,没有配置property,loginService则为空
所以会产生两种struts与spring的配置方案:
(1)配置方案一:
在配置Action时,需要将class属性和Spring配置文件中的相对应的Action的bean的Id的属性保持一致,系统即可通过Spring来装配和管理Action。
如果action包含了Service层的对象:
private StudentInfoServiceImpl studentInfoService;
则需要添加set方法,才可以使用Spring依赖注入:
public void setStudentInfoService(StudentInfoServiceImpl studentInfoService) {
this.studentInfoService = studentInfoService;
}
如果action在struts.xml如下配置:
<action name="studentRegister" class="studentRegisterAction"> <result name="result">/WEB-INF/exam/result.jsp </result> <result name="input">/WEB-INF/exam/error.jsp </result> <interceptor-ref name="excludeParamsStack" /> </action>
则在applicationContext.xml文件中该Action的配置如下:
<bean id="studentRegisterAction" class="com.exam.actions.StudentRegisterAction" scope="prototype"><!--指定多例-->
<property name="studentInfoService">
<ref bean="studentInfoService" />
</property>
</bean>
Struts2与Spring整合的方案二:
前面两个步骤和方案一的一样;
在配置struts.xml文件时,Action的class为该Action的类路径,而在applicationContext.xml配置文件中不需要添加Action的bean配置。这样,当我们使用Action类时,由于studentInfoService已经配置了相关的bean,所以会自动装配,并且action依然由spring进行实例化。
studentInfoService的配置:
<bean id="studentInfoService" class="com.exam.service.StudentInfoServiceImpl">
<constructor-arg>
<ref bean="studentInfoDAO" />
</constructor-arg>
</bean>
重点studentInfoService和action中的属性要一样!!
Action在struts.xml中的配置如下:
<action name="studentRegister" class="com.exam.actions.StudentRegisterAction"><!--struts2 默认多例--> <result name="result">/WEB-INF/exam/result.jsp </result> <result name="input">/WEB-INF/exam/error.jsp </result> <interceptor-ref name="excludeParamsStack" /> </action>