1.Spring與Web環境集成
1.1自定義監聽器將Spring集成到web環境
1_需求:將spring集成到web開發環境中,將所有的bean對象創建交給spring,除了servlet,servlet可以理解為一個測試類.在servlet中獲取ApplicationContext,獲取對應的bean
環境搭建,這個是自己一步步取實現的,其實spring有提供簡單的方法完成1.1的操作
<!--在pom文件中引入所需的依賴-->
<!--Spring坐標-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!--SpringMVC坐標-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!--Servlet坐標-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--Jsp坐標-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
//1.創建dao層接口和實現類
//dao接口 IUserDao
public interface IUserDao{
void save();
}
//UserDaoImpl實現類
public class UserDaoImpl implements IUserDao{
@Override
public void save(){
System.out.printLn("正在保存...");
}
}
//2.創建service業務層接口和實現類
public interface IUserService{
void save();
}
//UserServletImpl實現類
public class UserServiceImpl implements IUserService{
private IUserDao userDao;
//為依賴注入提供set方法
public void setUserDao(IUserDao userDao){this userDao=userDao;}
@Override
public void save(){
userDao.save();
}
}
<!--applicationContext.xml文件中配置Dao,service交給spring管理-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置Dao-->
<bean class="cn.ppvir.dao.impl.UserDaoImpl" id="userDao"></bean>
<!--配置service-->
<bean class="cn.ppvir.service.impl.UserServiceImpl" id="userService">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
/*web包下創建UserServlet類 內部功能:調Spring容器,創建service對象,調sava()方法*/
public class UserServlet extends HttpServlet{
@Override//復寫doGet方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//通過配置文件獲取上下文
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//獲取bean,因為只有一個UserServiceImpl,可以使用字節碼的方法獲取
UserServiceImpl userService = context.getBean(UserServiceImpl.class);
//調用save方法
userService.save();
}
}
<!--在web.xml中配置 servlet-->
<servlet>
<servlet-name>userServlet</servlet-name>
<servlet-class>cn.ppvir.web.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userServlet</servlet-name>
<url-pattern>/userServlet</url-pattern>
</servlet-mapping>
最后配置tomcat,啟動測試
http://localhost:80/userServlet
2_問題描述:
spring在web開發環境下,每個servlet都需要new ClassPathXmlApplicationContext("applicationContext.xml")
因為配置文件會加載多次,所以會造成性能浪費
3_改進一:
將ApplicationContext對象的創建交給監聽器創建,監聽器將創建好的對象存入ServletContext域對象中,在servlet中直接獲取該對象.
- 編寫監聽器代碼
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//獲取上下文
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//將spring獲取到的應用上下文,保存到servletContext域中
ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute("context",context);
//之后去web.xml配置listener監聽器和改寫servlet代碼
}
- 監聽器配置
web.xml
<!--配置servlet-->
<!--配置自己實現的監聽器-->
<listener>
<listener-class>cn.ppvir.listener.ContextLoaderListener</listener-class>
</listener>
- servlet代碼改寫
public class UserServlet extends HttpServlet {
/**
* 改進一:
* 將ApplicationContext對象的創建交給監聽器創建,監聽器將創建好的對象存入ServletContext域對象中,在servlet中直接取該對象即可
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取servletContext域對象
ServletContext servletContext = this.getServletContext();
//從ServletContext域對象中,獲取監聽器創建的應用上下文,強轉為ApplicationContext
ApplicationContext context = (ApplicationContext) servletContext.getAttribute("context");
UserServiceImpl userService = context.getBean(UserServiceImpl.class);
userService.save();
}
}
重啟tomcat完成測試.
4.優化二:
- 1_在web.xml文件中配置要加載的applicationContext.xml文件
web.xml
<!--改進二: 之前的基礎上添加配置-->
<!--全局初始化參數-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
- 2.改寫ContextLoaderListener監聽器類,獲取全局初始化參數
public class ContextLoaderListener implements ServletContextListener {
/**
* 優化二: 獲取全局初始化參數
*
* @param servletContextEvent
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//獲取域對象
ServletContext servletContext = servletContextEvent.getServletContext();
//從配置文件中獲取applicationContext
/*
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
*/
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
//獲取應用上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(contextConfigLocation);
//將Spring的應用上下文 存儲到ServletContext域對象中
servletContext.setAttribute("context",context);
System.out.println("spring容器創建完畢...");
}
}
- 3.優化強轉ApplicationContext,使用工具類直接從servletContext域對象中獲取applicationContext對象.
//創建工具類
package cn.ppvir.listener;
import org.springframework.context.ApplicationContext;
import javax.servlet.ServletContext;
/**
* 工具類,強轉context上下文為ApplicationContext
*/
public class WebApplicationContextUtils {
/**
* @param servletContext 參數是域對象
* @return 返回值是強轉后的對象ApplicationContext
*/
public static ApplicationContext getWebapplicationContext(ServletContext servletContext){
return (ApplicationContext)servletContext.getAttribute("context");
}
}
- 4.修改UserServlet類使用WebApplicationContextUtils優化強轉context
public class ContextLoaderListener implements ServletContextListener {
/**
* 優化二: 使用WebApplicationContextUtils工具類,簡化強轉上下文對象的操作
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取域對象
ServletContext servletContext = this.getServletContext();
ApplicationContext context = WebApplicationContextUtils.getWebapplicationContext(servletContext);
UserServiceImpl userService = context.getBean(UserServiceImpl.class);
userService.save();
}
}
重啟tomcat完成測試
1.2使用spring提供的監聽器將spring集成到web環境
UserDao和UserService層與上面一樣
- 導入依賴
pom.xml
<!--spring-web坐標-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
- 配置Spring提供的監聽器ContextLoaderListener
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!--全局參數-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--監聽器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置servlet-->
<servlet>
<servlet-name>service</servlet-name>
<servlet-class>web.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>service</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- applicationContext.xml配置讓spring管理注入
applicationContext.xml
<bean class="dao.impl.UserDaoImpl" id="userDao"></bean>
<bean class="service.impl.UserServiceImpl" id="userService">
<property name="userDao" ref="userDao"></property>
</bean>
- servlet中通過工具獲得應用上下文對象
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取servletContext域對象
ServletContext servletContext = this.getServletContext();
//使用spring框架自帶的WebApplicationContextUtils工具,獲取上下文對象
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserServiceImpl userService = context.getBean(UserServiceImpl.class);
userService.save();
}
}
1.3小結:
1.web環境中集成spring只需要配置監聽器即可
2.Spring負責管理處=除了controller以外的所有bean對象