web启动@Autowired不能自动注入
使用struts2,下面为action代码
Java代码
package com.edar.web.platform; import org.apache.struts2.convention.annotation.InterceptorRef; import org.apache.struts2.convention.annotation.InterceptorRefs; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import com.edar.components.AccountBean; import com.edar.dao.util.Page; import com.edar.model.Account; import com.edar.service.platform.AccountService; import com.edar.web.struts2.GenericAction; @Component @Namespace("/platform") @InterceptorRefs( { @InterceptorRef("paramsPrepareParamsStack") }) @Results( { @Result(name = GenericAction.RELOAD, location = "account.action", type = "redirect") }) public class AccountAction extends GenericAction<AccountBean> { private static final long serialVersionUID = 1900042912756344244L; @Autowired @Qualifier("accountServiceImpl") private AccountService accountService; private AccountBean accountBean; private Page<AccountBean> page = new Page<AccountBean>(16,true); public AccountBean getAccountBean() { return accountBean; } public void setAccountBean(final AccountBean accountBean) { this.accountBean = accountBean; } public Page<AccountBean> getPage() { return page; } public void setPage(final Page<AccountBean> page) { this.page = page; } @Override public String delete(){ accountService.delete((Account) dozer.map(accountBean, Account.class)); return SUCCESS; } @Override public String list(){ page = accountService.getPage(accountBean); return SUCCESS; } @Override protected void prepareModel(){ if(accountBean==null){ accountBean = new AccountBean(); }else{ if(accountBean.getAccountId()!=null){ accountBean = (AccountBean)dozer.map(accountService.getAccount(accountBean.getAccountId()), AccountBean.class); } } } @Override public String save(){ Account account = (Account) dozer.map(accountBean, Account.class); accountService.save(account); accountBean.setAccountId(account.getAccountId()); return SUCCESS; } public AccountBean getModel() { return accountBean; } }
此action的junit测试代码
package com.edar.web.platform; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.edar.components.AccountBean; import com.edar.test.SpringContextTestCase; public class AccountActionTest extends SpringContextTestCase{ private static Long accountId; @Autowired private AccountAction accountAction; @BeforeClass public static void setUpBeforeClass() throws Exception { } @AfterClass public static void tearDownAfterClass() throws Exception { } @Before public void setUp() throws Exception { AccountBean bean = new AccountBean(); bean.setName("ysheng53"); bean.setMobile("13819181747"); bean.setEmail("ysheng53@gmail.com"); bean.setPasswd("321"); accountAction.setAccountBean(bean); } @After public void tearDown() throws Exception { } @Test public void testSave() { String result = accountAction.save(); accountId = accountAction.getAccountBean().getAccountId(); Assert.assertEquals(AccountAction.SUCCESS, result); } @Test public void testList() { String result = accountAction.list(); Assert.assertEquals(AccountAction.SUCCESS, result); Assert.assertTrue(" 结果数小于0了 ",accountAction.getPage().getTotal()>0); } @Test(timeout=5000) public void testDelete() { accountAction.getAccountBean().setAccountId(accountId); String result = accountAction.delete(); Assert.assertEquals(AccountAction.SUCCESS, result); Assert.assertTrue("<=0",accountAction.getPage().getTotal()<=0); } }
注意到action中的代码:
Java代码
@Autowired@Qualifier("accountServiceImpl")private AccountService accountService;
现象时,在junit测试代码执行时,accountService能够被注入,但是用tomcat6,在eclipse,wtp中启动时,accountService没有被注入,为null!
问题在查,谁遇到过类似问题;
问题补充
经过测试分析发现:
AccountAction在junit测试时用spring注入进去,而且只有唯一一个;
而在struts2中,每次请求都会有一个AccountAction的实例;
现在的问题是,struts2中新建实例时,那个private AccountService accountService;自动注入无效;
注:使用了Conventian Plugin
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"><struts><constant name="struts.convention.default.parent.package" value="crud-default" /><constant name="struts.convention.package.locators" value="web" /><!-- 用于CRUD Action的parent package --><package name="crud-default" extends="convention-default"><!-- 基于paramsPrepareParamsStack,增加store interceptor保证actionMessage在redirect后不会丢失 --><interceptors><interceptor-stack name="crudStack"><interceptor-ref name="store"><param name="operationMode">AUTOMATIC</param></interceptor-ref><interceptor-ref name="paramsPrepareParamsStack" /></interceptor-stack></interceptors><default-interceptor-ref name="crudStack" /></package><!-- 使用Convention插件,实现约定大于配置的零配置文件风格. 特殊的Result路径在Action类中使用@Result设定. --></struts>
struts.properties配置如下:
struts.devMode = truestruts.locale=zh_cnstruts.i18n.encoding=utf-8struts.objectFactory=spring
如未解决,请你贴一下你的配置以及相关spring,struts2的包