使用spring访问servlet
首先先建一个web项目,并在pom.xml中引入依赖包:spring-context和jsp servlet相关包,以及tomcat插件
其次建一个spring的配置文件applicationContext.xml,并在配置中开启注解扫描:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <!--开启扫描--> <context:component-scan base-package="com.zy"></context:component-scan> </beans>
注意我们先演示一个有问题的方式:
我们模拟从index.jsp 访问 LoginServlet:
UserService
public interface UserService { public boolean login(); } @Service("userService")//使用注解 public class UserServiceImpl implements UserService { public UserServiceImpl() { System.out.println("userService 构造方法..."); } @Override public boolean login() { System.out.println("service login..."); return true; } }
index.jsp
<%@ page contentType="text/html; charset=utf-8" language="java" isELIgnored="false" %> <html> <body> <h2>Hello World!</h2> <a href="${pageContext.request.contextPath}/HelloServlet">helloservlet</a> </body> </html>
LoginServlet
public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService service = ac.getBean("userService", UserService.class);//spring容器创建service对象 boolean isOk = service.login(); response.setContentType("text/html;charset=utf-8"); if (isOk) { response.getWriter().print("登录成功,3秒跳转index页面"); response.setHeader("refresh", "3;url=" + request.getContextPath() + "/index.jsp"); }else { response.getWriter().print("登录失败"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
运行tomcat点击了两次index页面上的超链接(访问了两次LoginServlet),后台输出为:
前台页面也显示登录成功,可以看出访问servlet是成功了,但是有一个问题:
问题是每次访问servlet都会重新创建UserService对象,现在我们只有一个对象,如果以后有很多个对象,那每次访问servlet的时候,
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
这句代码都会把对象创建出来,会很浪费资源,那么怎么解决这个问题呢?
现在我们演示正确的方式:
添加监听器,用来监听程序启动,当启动的时候,把所有的对象都创建出来,以后再用的之后直接用,不再创建:
web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--告诉监听器spring配置文件是谁--> <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-name>HelloServlet</servlet-name> <servlet-class>com.zy.web.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet</url-pattern> </servlet-mapping> </web-app>
上面配置监听器的ContextLoaderListener,需要在pom.xml中引入下面这个包:
<!--web.xml中需要配置监听器,这里就需要导入这个包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.1.3.RELEASE</version> </dependency>
这次我们加上dao层:
public interface UserDao { public boolean login(); } @Repository("userDao") public class UserDaoImpl implements UserDao { public UserDaoImpl() { System.out.println("userDao 构造方法..."); } @Override public boolean login() { System.out.println("dao login..."); return true; } }
service:
public interface UserService { public boolean login(); } @Service("userService") public class UserServiceImpl implements UserService { @Value("#{userDao}")//注入UserDao private UserDao userDao; public UserServiceImpl() { System.out.println("userService 构造方法..."); } @Override public boolean login() { System.out.println("service login..."); return userDao.login(); } }
配置完成以后,LoginServlet中获取ApplicationContext的方式改变一下:
public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); //使用下面的方法 从工具类中获取ApplicationContext 需要把当前servlet的ServletContext当做参数传进去 ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); UserService service = ac.getBean("userService", UserService.class); boolean isOk = service.login(); response.setContentType("text/html;charset=utf-8"); if (isOk) { response.getWriter().print("登录成功,3秒跳转index页面"); response.setHeader("refresh", "3;url=" + request.getContextPath() + "/index.jsp"); } else { response.getWriter().print("登录失败"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
当程序启动的时候,两个实现类都被创建出来了:
这样,每次访问LoginServlet的时候,就不会重复创建对象了,只会调用对象的方法(访问了两次):