zoukankan      html  css  js  c++  java
  • 在Spring容器外调用bean

    这个东西源于这种需求:一个应用丢到服务其后,不管用户有没有访问项目,这个后台线程都必须给我跑,而且这个线程还调用了Spring注入的bean,这样自然就会想到去监听Servlet的状态,当Servlet初始化完毕后会调用ServletContextListener中的contextInitialized方法,所以可以创建一个监听器继承ServletContextListener类来监听Servlet的状态,在contextInitialized方法中来启动后台的线程,但是如何使用Spring注入的bean呢?所以必须确保在启动线程前Spring容器必须初始化完毕,Spring的初始化也是有Listener完成的,所以这里特别注意的是自定的监听器必须放在Spring的监听器之后(很重要),否则无法获取bean属性,会报空指针异常!

    1.创建监听器

    package com.hhu.listener;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import com.hhu.threads.DiagnosisThread;
    
    /**
     * 这个监听器在WEB容器初始化后就立刻启用了
     * @author Weiguo Liu
     * @data 2017年11月30日
     */
    
    public class ContextListener implements ServletContextListener  {
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("加载应用程序...");
    //      StationService stationService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean(StationService.class);
    //      System.out.println("stationService=" + stationService);
    
            /*
             * 创建诊断线程并启动
             */
            DiagnosisThread dt = new DiagnosisThread();
            dt.start();
            System.out.println("Listener继续执行");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            // TODO Auto-generated method stub
    
        }
    
    }
     

    2.web.xml配置启动顺序

      <!-- 这里不能少,web启动后会按这个位置寻找Spring的配置文件 -->
         <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:spring/spring-*.xml
            </param-value>
        </context-param>
    
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
      <listener>
        <listener-class>
            com.hhu.listener.ContextListener
        </listener-class>
      </listener>
    
        <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring/spring-*.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
    
        <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
     

    3.写一个获取Spring Bean的工具类

    由于ServletContextListener并不被Spring管理,所以我们不能使用@Autowired注解来获取相应的bean属性,而是利用ApplicationContext来获取Bean,代码如下

    package com.hhu.util;
    
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    /**
     * 使用getBean可以获取对应的bean,自己的的手动进行类型强转
     * 创建获取SpringBean的工具类
     * @author Weiguo Liu
     *
     */
    public class SpringBeanUtil implements ApplicationContextAware {
        private static ApplicationContext applicationContext = null;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            SpringBeanUtil.applicationContext = applicationContext;
        }
    
        public static Object getBeanByName(String beanName) {
            if (applicationContext == null) {
                return null;
            }
            return applicationContext.getBean(beanName);
        }
    
        public static <T> T getBean(Class<T> type) {
            return applicationContext.getBean(type);
        }
    }

    这样以后就可以在后台线程中愉快的获取Spring bean了,这个工具类很强大,只要Spring初始化后,不管所在类是否被Spring管理,都可以使用如下的方式获取

    bean的类型 bean的名字 = (bean的类型)SpringBeanUtil.getBeanByName("bean的名字");

    做的越多,也就发现自己不懂的越多,还是要深入理解其原理啊

  • 相关阅读:
    js 使用${}解析变量代替++
    laravel 返回自定义错误
    Java集合之HashMap源码解析
    Java集合之ArrayList源码解析
    Java集合之LinkedList源码解析
    保证消息可靠性传输以及幂等性
    Java分布式系统---消息中间件
    Java中的日期与时间
    Java时区问题
    数据测试002:利用Jmeter推送测试数据(上)
  • 原文地址:https://www.cnblogs.com/weixupeng/p/10459583.html
Copyright © 2011-2022 走看看