Spring与Web整合之监听器创建ApplicationContext工具类

创建一个简单的UserDao层

public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("userDaoImpl save.....");
    }
}

然后写个简单的Service层

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        userDao.save();
    }
}

applicationContext.xml中注入对象并配置组件扫描

 <!--配置组件扫描-->
    <context:component-scan base-package="com.uncleChen"/>
    <bean id="userDao" class="com.uncleChen.dao.impl.UserDaoImpl"></bean>
    <bean id="userService" class="com.uncleChen.service.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>

在Servlet中直接获取ApplicationContext然后获取Service对象再调用save方法

@WebServlet(name = "userServlet", value = "/userServlet")
public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
    UserService userService = app.getBean("userService", UserService.class);
        userService.save();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

在开启服务器之后,用户每访问一次Servlet就会创建一个ApplicationContext对象,为了方便,可以使用监听器在项目启动时就创建好ApplicationContext对象,再将该对象放入上下文,每次用户访问Servlet都会调用放入上下文那个ApplicationContext对象

配置全局初始化参数将Spring配置文件与监听器解耦

<!--    web全局初始化参数-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>applicationContext.xml</param-value>
    </context-param>

再写一个简单的监听器

@WebListener
public class ContextLoaderListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
        ApplicationContext app=
                new ClassPathXmlApplicationContext(contextConfigLocation);
        //在上下文公共域中添加applicationContext对象便于Servlet层访问
        servletContext.setAttribute("app",app);
        //测试监听器
        System.out.println("spring容器创建完毕");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //do something...
    }
}

此时修改Servlet内容为:

public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        //获取监听器提前放入ServletContext中的ApplicationContext对象
        ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
        UserService userService = app.getBean("userService", UserService.class);
        userService.save();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

目前看来,只有一个Servlet的时候直接把ServletContext域中ApplicationContext的名称(在这里叫"app")写进Servlet没什么问题,但是多个Servlet都可以访问同一个ApplicationContext时就要每一个Servlet都写一次名称(这里还叫"app")很麻烦,耦合也很高,所以还可以创建一个工具类,专门提供ApplicationContext对象

创建工具类WebApplicationContextUtils

传入上下文ServletContext对象,返回监听器提前放入ServletContext中的ApplicationContext对象

public class WebApplicationContextUtils {
    public static ApplicationContext getWebApplicationContext(ServletContext servletContext){
    return (ApplicationContext) servletContext.getAttribute("app");
    }
}

此时Servlet可以写成:

public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService = app.getBean("userService", UserService.class);
        userService.save();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

运行结果:

监听器正常工作

访问资源后:

正常调用save方法

Spring提供的工具类直接使用

依赖注入

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

先要把自己写的监听器注解去掉,再在web.xml中配置

<!--    配置监听器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

然后直接使用即可

import com.uncleChen.service.UserService;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

/**
 * @author uncleChen
 * @version 1.0
 * @date 2022/2/17 1:10
 */
@WebServlet(name = "userServlet", value = "/userServlet")
public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        WebApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService = app.getBean("userService", UserService.class);
        userService.save();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_53132064

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值