看了黑马姜涛老师讲解的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中的操作。