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对象