看了黑馬姜濤老師講解的SSH整合,在
在這個圖中很疑惑爲什麼不直接把Action交給Spring管理,直接注入Service即可
<bean name="CustomerAction" class="com.awf.sshIntegrate.web.action.CustomerAction">
<property name="CustomerService" ref="CustomerService"/>
</bean>
試了之後發現不能這麼做,測試報錯
19:11:21,885 ERROR DefaultDispatcherErrorHandler:42 - Exception occurred during processing request: null
java.lang.NullPointerException
at com.awf.sshIntegrate.web.action.CustomerAction.save(CustomerAction.java:37)
這是因爲Action是由Struts獲得請求後創建
若是直接以上述方式實現,就存在兩個Action了,第一個由Struts2獲得請求創建,第二個是由Spring創建
第一個Action創建之後執行service.save(),因爲他並不是由Spring創建,也就沒有service注入進來,所以null。
所以正常來說必須通過
WebApplicationContext application = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext());
CustomerService customerService = (CustomerService)application.getBean("CustomerService");
customerService.save(customer);
來調用Spring創建的service,即可正常執行。
不過Struts2提供了 struts2-spring-plugin-2.3.24.jar 插件簡化上述操作,把action交由Spring管理。
在插件中有如下屬性配置,對象工廠交由Spring創建
<!-- Make the Spring object factory the automatic default -->
<constant name="struts.objectFactory" value="spring" />
Action中代碼即可改爲
private CustomerService customerService;
public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}
public String save() {
System.out.println("CustomerAction執行了。。。");
// WebApplicationContext application = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext());
// CustomerService customerService = (CustomerService)application.getBean("CustomerService");
customerService.save(customer);
return NONE;
}
Action即可根據名稱使用Spring中的Service對象
<bean name="customerService" class="com.awf.sshIntegrate.service.impl.CustomerServiceImpl">
<property name="CustomerDao" ref="CustomerDao"/>
</bean>
測試通過,簡化的Action中的操作。