`

在Listener、Filter、Servlet中调用 spring 使用注解定义的bean

阅读更多

1.背景

    ServletContext,是一个全局的储存信息的空间,服务器开始建立,服务器关闭销毁。request,每次请求一个;session,一个会话一个;而servletContext,所有用户共用一个。

    ServletContext维护着一个服务器中的一个特定URL名字空间(比如,/myapplication)下的所有Servlet,Filter,JSP,JavaBean等Web部件的集合。

    也就是说Servlet和Filter并不是由Spring ApplicationContext维护的,所以使用autowire注解来进行注入会产生问题。

一般都是通过下面这个方法解决

WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(servletContextEvent.getServletContext());

  

2.准备工作

准备一个由Spring ApplicationContext维护Bean,分别在Listener、Filter和Servlet中调用其中的方法。

 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component("springBean")
public class SpringBean {

    private static final Logger logger = LoggerFactory.getLogger(SpringBean.class);

    public void listener() {
        logger.info("listener use spring bean");
    }

    public void servlet() {
        logger.info("servlet use spring bean");
    }

    public void filter() {
        logger.info("filter use spring bean");
    }


}

 

 

 

2.Listener

1.web.xml

<!-- test listener use spring bean -->
<listener>
    <listener-class>com.gqshao.spring.listener.MyListener</listener-class>
</listener>

 

 

 

2.MyListener

package com.gqshao.spring.listener;

import com.gqshao.spring.bean.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * 功能说明:测试自定义Listener使用spring使用注解定义的bean
 */
public class MyListener implements ServletContextListener {

    private static final Logger logger = LoggerFactory.getLogger(MyListener.class);


    @Override
    public void contextInitialized(ServletContextEvent event) {
        WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
        SpringBean bean = (SpringBean) springContext.getBean("springBean");
        bean.listener();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        logger.info("MyListener contextDestroyed");
    }
}

 

 

3.Filter

针对Filter,Spring提供了DelegatingFilterProxy解决

 

1.web.xml

<!-- test filter use spring bean -->
<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>myFilter</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

 

2.applicationContext.xml

<bean name="myFilter" class="com.gqshao.spring.filter.MyFilter"/>

 

3.MyFilter

package com.gqshao.spring.filter;


import com.gqshao.spring.bean.SpringBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

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

public class MyFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(MyFilter.class);

    @Autowired
    private SpringBean springBean;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.info("MyFilter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        springBean.filter();
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        logger.info("MyFilter destroy");
    }
}

 

3.Servlet

Servlet我们仿照Spring对Filter的处理写一个DelegatingServletProxy这样的代理Servlet

 

1.web.xml

<!-- test servlet use spring bean -->
<servlet>
    <servlet-name>myServlet</servlet-name>
    <servlet-class>com.gqshao.spring.servlet.DelegatingServletProxy</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>myServlet</servlet-name>
    <url-pattern>/testservlet</url-pattern>
</servlet-mapping>

 

2.DelegatingServletProxy

package com.gqshao.spring.servlet;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

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

public class DelegatingServletProxy extends GenericServlet {

    private String targetBean;
    private Servlet proxy;

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException,
            IOException {
        proxy.service(request, response);
    }

    @Override
    public void init() throws ServletException {
        this.targetBean = getServletName();
        setServletBean();
        proxy.init(getServletConfig());
    }

    private void setServletBean() {
        WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        this.proxy = (Servlet) wac.getBean(targetBean);
    }
}

 

3.MyServlet

package com.gqshao.spring.servlet;

import com.gqshao.spring.bean.SpringBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Component
public class MyServlet extends HttpServlet {

    @Autowired
    private SpringBean springBean;

    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        springBean.servlet();
        PrintWriter out = response.getWriter();
        out.println("<h3>Hello World</h3>");
        out.flush();
        out.close();
    }
}

 

4.说明

MyServlet使用Spring ApplicationContext来维护,通过@Component来定义

DelegatingServletProxy 通过web.xml文件中servlet-name中的值在Spring ApplicationContext中查找MyServlet,注意名称一致。

分享到:
评论

相关推荐

    特殊情况(ActionForm,Servlet, Filter, Listener)下Spring如何注入对象

    2. **Filter**: 同样,可以在Filter的init()方法中获取ApplicationContext,或者通过ServletContextAware接口,将Spring上下文注册到ServletContext,然后在doFilter()方法中使用。 3. **Listener**: 在监听器的...

    Spring注解驱动开发实战-servlet

    在Spring注解驱动的开发中,`ServletContext`用于注册三大组件:Servlet、Filter和Listener。例如,我们可以通过`@WebServlet`、`@WebFilter`和`@WebListener`注解分别创建这些组件,并将它们直接声明在类上,而无需...

    Spring源码深度解析与注解驱动开发1

    6. 声明式事务:在Spring中,我们可以使用@Transactional注解实现声明式事务管理,无需手动调用begin、commit、rollback等事务操作。 二、扩展原理 1. `BeanFactoryPostProcessor`:这是一个接口,允许在所有bean...

    SpringBoot学习笔记完整教程

    12. **普通类调用 Bean**:Spring Boot 的依赖注入机制使得 Bean 可以在非 Controller 类中被注入和使用。学习如何在非 Spring 管理的组件中获取和使用 Spring 管理的 Bean。 13. **使用模板引擎**:Spring Boot ...

    spring-web

    在源码中,你可以看到`web.xml`配置文件,这是传统的Servlet容器配置方式,其中会定义`DispatcherServlet`和其他必要的Servlet、Filter和Listener。Spring Boot引入的自动配置使得配置更加简洁,但这里我们可能仍能...

    Spring Boot 学习笔记完整教程new

    12. **普通类调用Bean**:在非Spring管理的类中注入并使用Spring Bean,可以使用ApplicationContext来获取Bean实例。 13. **使用模板引擎**:Spring Boot支持多种模板引擎,如Thymeleaf和FreeMarker,用于生成动态...

    Spring boot +jdbctemplate

    - **WebApplicationInitializer**:Spring Boot自动配置Servlet、Filter和Listener,无需传统web.xml配置。 - **DispatcherServlet**:Spring Boot会默认创建一个DispatcherServlet,处理所有HTTP请求。 - **...

    MyBatis3整合Spring3,SpringMVC

    在现代企业级应用开发中,MyBatis、Spring 和 SpringMVC 是非常重要的技术栈组合。通过整合这三者,可以构建出功能强大、结构清晰且易于维护的应用系统。本文将详细介绍如何实现 MyBatis3 与 Spring3 及 SpringMVC ...

    javaSSH框架搭建配置

    在`web.xml`中,通过`ContextLoaderListener`来加载Spring的配置文件,从而初始化Spring容器。这里的关键配置包括: ```xml &lt;!--Spring--&gt; &lt;listener&gt; &lt;listener-class&gt;org.springframework.web.context....

    为java web项目添加spring MVC框架

    在本例中,这个文件应包含Spring的Bean定义,比如数据源、DAO层、服务层等。 #### 2. springMVCTemplet-servlet.xml 这个文件是Spring MVC的配置文件,专门用于配置与Web相关的Bean。例如,内部资源视图解析器...

    Servlet与JSP核心编程原码.zip_law5x6

    Servlet 3.0引入了注解式配置,可以不用`web.xml`文件直接在类上声明Servlet和过滤器。此外,支持异步处理,使得Servlet能执行长时间运行的任务而不阻塞线程。 12. **JSP动作标签** JSP动作标签如`&lt;jsp:include&gt;`...

    JavaEE开发的颠覆者SpringBoot实战[完整版].part3

    在当今Java EE 开发中,Spring 框架是当之无愧的王者。而Spring Boot 是Spring 主推的基于“习惯优于配置”的原则,让你能够快速搭建应用的框架,从而使得Java EE 开发变得异常简单。 《JavaEE开发的颠覆者: Spring ...

    ssh框架demo Struts2.0+Spring3.0+hibernate

    - 在本Demo中,Spring可能通过XML配置或注解方式配置了Bean,例如定义了UserDAO和UserService。 - Spring的AOP可以用于事务管理,例如,当用户注册或登录时,确保数据操作在同一个事务中完成。 3. **Hibernate**...

    Spring工程源代码

    - `src/main/webapp`:Web应用目录,包括`WEB-INF`目录下的`web.xml`(Web应用部署描述符),用来配置Servlet、Filter和Listener;`jsp`页面、静态资源(CSS、JavaScript)等也存放于此。 在SpringMVC中,主要流程...

    JavaEE开发的颠覆者SpringBoot实战[完整版].part2

    在当今Java EE 开发中,Spring 框架是当之无愧的王者。而Spring Boot 是Spring 主推的基于“习惯优于配置”的原则,让你能够快速搭建应用的框架,从而使得Java EE 开发变得异常简单。 《JavaEE开发的颠覆者: Spring ...

    springMVC+spring+mybatis+maven多模块web项目源码例子 实用框架

    在`WEB-INF`目录下,通常会存放`web.xml`,这是Web应用的部署描述符,用于配置Servlet、Filter和Listener等。`META-INF`目录则通常包含Maven的MANIFEST.MF文件,记录了关于JAR或WAR文件的元数据。 在实际使用这个...

    框架ssm整合

    在`applicationContext.xml`中配置Spring的bean定义,例如: ```xml &lt;!-- 数据源 --&gt; &lt;bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"&gt; ;serverTimezone=UTC"/&gt; &lt;/bean&gt; &lt;!-- ...

    基于javaweb的档案管理系统+Spring+SpringMVC+MyBatis源码.rar

    1. **JavaWeb基础**:JavaWeb是Java技术在Web应用中的运用,它涵盖了Servlet、JSP、Filter、Listener等核心组件。开发者需要理解HTTP协议,以及如何通过Servlet来处理HTTP请求和响应。 2. **Spring框架**:Spring是...

    JavaEE开发的颠覆者SpringBoot实战[完整版].part1

    在当今Java EE 开发中,Spring 框架是当之无愧的王者。而Spring Boot 是Spring 主推的基于“习惯优于配置”的原则,让你能够快速搭建应用的框架,从而使得Java EE 开发变得异常简单。 《JavaEE开发的颠覆者: Spring ...

Global site tag (gtag.js) - Google Analytics