JavaWeb学习:Struts2与Spring的IOC练习
需求:把客户信息存储到数据库中
一、创建web项目,搭建基盘
二、创建实体类
public class Customer { private Long cust_id; private String cust_name; private String cust_source; private String cust_industry; private String cust_level; private String cust_phone; private String cust_mobile;
三、搭建struts2环境
①、引入struts2的开发jar包
②、配置struts2的核心过滤器
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
③、编写Action
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> { // 使用模型驱动获取页面上的值 Customer customer=new Customer(); @Override public Customer getModel() { return customer; } public String saveUI() { return "saveUI"; } }
④、在src下新建strust.xml,添加以下内容
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <package name="crm" extends="struts-default" namespace="/"> <global-allowed-methods>regex:.*</global-allowed-methods> <action name="customer_*" class="com.xxx.crm.web.action.CustomerAction" method="{1}"> <result name="saveUI">/jsp/customer/add.jsp</result> </action> </package> </struts>
⑤、测试struts2环境
<A class=style2 href="${ pageContext.request.contextPath }/customer_saveUI.action" target=main>- 新增客户</A>
⑥、编写客户信息保存页面
<FORM id=form1 name=form1 action="${pageContext.request.contextPath }/customer_save.action" method=post>
编写Action的save方法,需要实例化Service的接口实现类,这样的话Action与Service属于紧耦合,所以需要使用Spring解耦
四、搭建Spring环境
①、引入jar包
②、通过配置将Service交给Spring,在src下新建applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="customerService" class="com.xxx.crm.service.impl.CustomerServiceImpl"></bean> </beans>
③、Action中调用Service
public String save() { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml"); CustomerService customerService=(CustomerService) applicationContext.getBean("customerService"); System.out.println("CustomerAction中的save方法执行了"); customerService.save(customer); return NONE; }
④、Service接口和实现类
//接口============== public interface CustomerService { public void save(Customer customer); } //实现类============= public class CustomerServiceImpl implements com.xxx.crm.service.CustomerService { @Override public void save(Customer customer) { System.out.println("CustomerService的save方法执行了"); } }
以上可以测试。
⑤、Service的接口实现类需要调用DAO层的方法,为了解耦DAO交给Spring管理
<bean id="customerDao" class="com.xxx.crm.service.impl.CustomerDaoImpl"></bean>
⑥、DAO接口和实现类
//接口============== public interface CustomerDao { public void save(Customer customer); } //实现类============= public class CustomerDaoImpl implements CustomerDao { public void save(Customer customer) { System.out.println("CustomerDao中的save方法执行了"); } }
⑦、Service中使用DAO
在Action使用Service时已经加载过applicationContext.xml了,就已经创建了Service和DAO了,所以就不需要再加载applicationContext.xml了。并且Service和DAO都是被Spring管理的,所以可以使用依赖注入的方式获取DAO的对象
Ⅰ、编写Service实现类的方法
public class CustomerServiceImpl implements com.xxx.crm.service.CustomerService { private CustomerDao customerDao; public void setCustomerDao(CustomerDao customerDao) { this.customerDao = customerDao; } @Override public void save(Customer customer) { System.out.println("CustomerService的save方法执行了"); customerDao.save(customer); } }
Ⅱ、Spring的属性注入(可以发现Spring的属性注入的前提:1、一个类要被另一个类使用,2、这两个类都必须是Spring管理的)
<bean id="customerService" class="com.xxx.crm.service.impl.CustomerServiceImpl"> <property name="customerDao" ref="customerDao"/> </bean>
五、问题
上述案例每次请求都会创建Spring的工厂,浪费服务器资源
解决:
在服务器启动的时候创建Spring的工厂
将工厂存储到ServletContext中
每次请求从ServletContext中获取
使用Spring核心监听器(ContextLoaderListener)
①、引入jar包
spring-web.jar
②、配置监听器
<!-- 指定 Ioc容器(就是applicationContext.xml)的位置 --> <context-param> <!-- 监听器的父类ContextLoader中有一个属性contextConfigLocation, 该属性值 保存着 容器配置文件applicationContext.xml的位置 --> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <!-- 配置spring-web.jar提供的监听器,此监听器 可以在服务器启动时 初始化Ioc容器。 初始化Ioc容器(applicationContext.xml) 1.告诉监听器 此容器的位置:context-param 2.默认约定的位置 :WEB-INF/applicationContext.xml --> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
③、在Action中获取工厂
public String save() { ServletContext servletContext=ServletActionContext.getServletContext(); WebApplicationContext applicationContext=WebApplicationContextUtils.getWebApplicationContext(servletContext); //ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml"); CustomerService customerService=(CustomerService) applicationContext.getBean("customerService"); System.out.println("CustomerAction中的save方法执行了"); customerService.save(customer); return NONE; }