当前位置: 代码迷 >> Web前端 >> web起动@Autowired不能自动注入
  详细解决方案

web起动@Autowired不能自动注入

热度:432   发布时间:2012-10-11 10:16:10.0
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
1 楼 sys53 2010-02-22  
经过大量测试
发现struts2-spring没有配置好;

加上相应的包,同时objectFactory设为spring就解决了;
2 楼 volking 2010-06-05  
我也有这个问题。不过我发现,属性值能通过构造函数注入,但是还要加一个默认构造函数,否则action初始化错误。

属性注入null,怎么解决呢?
3 楼 volking 2010-06-05  
我也有这个问题。不过我发现,属性值能通过构造函数注入,但是还要加一个默认构造函数,否则action初始化错误。

属性注入null, 怎么解决呢?

注:我已经把struts2-spring-plugin放入lib里.
4 楼 sys53 2010-06-09  
volking 写道
我也有这个问题。不过我发现,属性值能通过构造函数注入,但是还要加一个默认构造函数,否则action初始化错误。

属性注入null, 怎么解决呢?

注:我已经把struts2-spring-plugin放入lib里.

struts.xml配置如下:
<?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 = true
struts.locale=zh_cn
struts.i18n.encoding=utf-8
struts.objectFactory=spring 


如未解决,请你贴一下你的配置以及相关spring,struts2的包
  相关解决方案