监听器 & 过滤器中注入 Bean 的问题

本贴最后更新于 1117 天前,其中的信息可能已经时移世异

前言

  之前提到过在使用 Redis 发布订阅模式解决集群环境下 WebSocket 通讯问题的时候,遇到了在监听器中无法使用 @Autowired 注解注入 bean 的问题,百度查询了一下,有多种解决方案,这里记录一下我使用的方案。

原因分析

  由于 Spring 启动对 IOC 容器初始化也是监听的 Servlet 的初始化之后才开始初始化,但是 Servlet 的初始化是由 Servlet 容器在启动时初始化的(一般我们使用的较多的就是 Tomcat),然后在初始化完 Servlet 之后在对过滤器&监听器进行初始化。这样就导致一个问题——由于监听器是由 Servlet 容器进行初始化的,他执行在 Spring IOC 容器初始化之前,导致我们自己本身定义的监听器不能被 Spring 初始化到 IOC 容器,就不能使用 Spring 的依赖注入特性了。

解决方案

  使用 Spring 提供的 ApplicationContext 获取实例,不使用注解注入。ApplicationContext 是 Spring 继 BeanFactory 之外的另一个核心接口或容器,允许容器通过应用程序上下文环境创建、获取、管理 bean。

代码实现

  封装了一个工具类,直接调用 getBean 方法即可。

/**
 * 获取实例上下文
 */
@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

扩展

  观察工具类代码,会发现 ApplicationContext 是一个静态变量,使用了 set 方法对 ApplicationContext 进行了初始化更新,但是 set 方法并不是静态方法。这样就会出现一个代码规范问题——不允许使用非静态方法更新静态字段,代码扫描也会给出相应提示: Make the enclosing method "static" or remove this set.

  如果把 ApplicationContext 修改为非静态变量,那么 getBean 也要相应的修改为非静态方法,因为静态方法不能调用非静态变量。如果将 getBean 修改为非静态方法,监听器中就不能直接使用工具类名调用方法,使用起来很不方便,于是找了其他办法来解决这个问题,后面会单独写一篇文章来记录。

  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    943 引用 • 1460 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...