在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,注意名称一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 KafkaListener 注解可以让 Spring Boot 应用轻松地消费 Kafka 消息。 步骤如下: 1. 引入 spring-kafka 依赖。 ```xml <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>2.2.2.RELEASE</version> </dependency> ``` 2. 在 Spring Boot 应用的配置文件配置 Kafka 生产者和消费者的相关信息。 ```yaml spring.kafka.bootstrap-servers=localhost:9092 spring.kafka.consumer.group-id=my-group spring.kafka.consumer.auto-offset-reset=earliest spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer ``` 3. 创建一个 Kafka 消费者,定义一个方法用于处理消息。 ```java @Component public class KafkaConsumer { @KafkaListener(topics = "my-topic", groupId = "my-group") public void receive(String message) { System.out.println("Received message: " + message); } } ``` 4. 创建一个 Kafka 生产者,发送消息。 ```java @Component public class KafkaProducer { @Autowired private KafkaTemplate<String, String> kafkaTemplate; public void send(String message) { kafkaTemplate.send("my-topic", message); } } ``` 5. 在任何需要发送消息的地方注入 KafkaProducer调用 send 方法发送消息即可。 ```java @Autowired private KafkaProducer kafkaProducer; public void sendMessage() { kafkaProducer.send("hello, kafka"); } ``` 以上就是使用 spring-kafka 的 KafkaListener 注解的基本使用方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值