监听器如何获取Spring配置文件

我们在做项目的时候,会用到监听器去获取spring的配置文件,然后从中拿出我们需要的bean出来,比如做网站首页,假设商品的后台业务逻辑都做好了,我们需要创建一个监听器,在项目启动时将首页的数据查询出来放到application里,即在监听器里调用后台商品业务逻辑的方法,也就是说我们需要在监听器里获取Spring中配置的相应的bean。先把监听器创建出来:

1. 创建InitDataListener

创建一个监听器InitDataListener继承ServletContextListener:

/**
 * @Description: TODO(用于项目启动的时候数据初始化)
 * @author shanheyongmu
 *
 */
//@Component //监听器是web层的组件,它是tomcat实例化的,不是Spring实例化的。不能放到Spring中
public class InitDataListener implements ServletContextListener {  

    private ProductService productService = null;//productService中定义了跟商品相关的业务逻辑  

    @Override
    public void contextDestroyed(ServletContextEvent event) {  

    }  

    @Override
    public void contextInitialized(ServletContextEvent event) {  

    }  

} 

并在web.xml中配置该监听器:

如上,productService中定义了商品的一些业务逻辑,并且这个productService是交给Spring管理的,那么我们如何得到这个对象呢?首先肯定的一点是:我们不能自己new出来,因为new出来的话就跟Spring的IoC没有关系了……主要有三种方式可以实现,我们先一个个分析,最后比较优劣。

2. 直接加载beans.xml文件

这种方式比较简单粗暴,不是要加载配置文件么?那好,我加载就是了,如下:

//@Component //监听器是web层的组件,它是tomcat实例化的,不是Spring实例化的。不能放到Spring中
public class InitDataListener implements ServletContextListener {  

    private ProductService productService = null; //productService中定义了跟商品相关的业务逻辑  

    @Override
    public void contextDestroyed(ServletContextEvent event) {  

    }  

    @Override
    public void contextInitialized(ServletContextEvent event) {
        // 获取业务逻辑类productService查询商品信息
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        productService = (ProductService) context.getBean("productService");
        System.out.println(productService); //输出看看拿到了没有       

                //下面是具体productService相关操作……
    }  

}

这种方法完全没问题,思路很清晰,先加载配置文件beans.xml,然后获取bean,但是启动tomcat后,我们看看控制台输出的信息:

到这里应该发现这种方式的弊端了,加载了两次配置文件,也就是说那些bean被实例化了两次,从打印的信息来看,是拿到我们自己加载配置文件是实例化的bean。这种方式明显不可取。

3. 从ServletContext中获取

从上面的方法中,我们最起码可以知道,Spring通过自己的监听器已经加载过一次配置文件了,我们没必要再加载一次,那么很容易想到,如果知道Spring加载后放到哪里了,那我们就可以从那地方获取该配置文件,下面我们看下Spring加载配置文件的过程:

上图中(省略了无关的代码),ContextLoaderListener就是web.xml中我们配置的Spring监听器,它也实现了ServletContextListener并继承了ContextLoader。在监听器中主要通过initWebApplicationContext方法来获取配置文件,并创建WebApplicationContext对象,在initWebApplicationContext方法里主要做两件事:一是拿到Spring的上下文,二是把Spring上下文放到ServletContext中,并且键为:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。那么如何拿到Spring的上下文呢?是通过获取web.xml中配置的Spring的路径,CONFIG_LOCATION_PARM其实是个字符串常量,就是上面web.xml中配置Spring监听器下面的:

<context-param>
      <param-name>contextConfigLocation</param-name> <!--CONFIG_LOCATION_PARM就是contextConfigLocation-->
      <param-value>classpath:beans.xml</param-value>
</context-param>  

所以就很明显了,通过web.xml中配置的路径拿到beans.xml,然后加载这个配置文件,实例化bean。

现在我们既然知道了Spring在加载配置文件后,把它放在了ServletContext中,那么我们就可以去这里面直接拿!

//@Component //监听器是web层的组件,它是tomcat实例化的,不是Spring实例化的。不能放到Spring中
public class InitDataListener implements ServletContextListener {  

    private ProductService productService = null;  

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // TODO Auto-generated method stub  

    }  

    @Override
    public void contextInitialized(ServletContextEvent event) {
        //  获取业务逻辑类查询商品信息  

        // 解决方案二,项目在启动时,把Spring配置文件通过Spring的监听器加载,存储到ServletContext中,我们只要在ServletContext中获取即可。
        ApplicationContext context = (ApplicationContext) event.getServletContext()
                                             .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        productService = (ProductService) context.getBean("productService");
        System.out.println(productService);
    }  

}

这样我们就可以拿到produceService的实例化对象了,这种方法好是好,就是getAttribute中的参数太长,也不知道当时程序员的脑门子被夹了还是咋地,估计是想不到其他更合适的名字了吧~

4. 通过Spring提供的工具类加载

也许开发Spring的大牛们也意识到了这个参数名字太长了,于是他们提供了一个方法类,可以加载配置文件:

public class InitDataListener implements ServletContextListener {  

    private ProductService productService = null;  

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // TODO Auto-generated method stub  

    }  

    @Override
    public void contextInitialized(ServletContextEvent event) {
        // 获取业务逻辑类查询商品信息  

        WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
        productService = (ProductService) context.getBean("productService");
        System.out.println(productService);
    }  

} 

其实,这里的getWebApplicationContext方法就是把上面的那个方法封装了一下而已,我们看看这个方法的源码就知道了:

public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
        return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
    }  

这样更加方便程序员调用,仅此而已……所以一般我们使用第三种方法来获取Spring的配置文件,从而获取相应的实例化bean。

时间: 2024-10-24 14:46:13

监听器如何获取Spring配置文件的相关文章

监听器如何获取Spring配置文件(加载生成Spring容器)

Spring容器是生成Bean的工厂,我们在做项目的时候,会用到监听器去获取spring的配置文件,然后从中拿出我们需要的bean出来,比如做网站首页,假设商品的后台业务逻辑都做好了,我们需要创建一个监听器,在项目启动时将首页的数据查询出来放到application里,即在监听器里调用后台商品业务逻辑的方法,也就是说我们需要在监听器里获取Spring中配置的相应的bean.先把监听器创建出来: 1. 创建InitDataListener 创建一个监听器InitDataListener继承Serv

在Java代码中获取spring配置文件中的配置项

曾嶷沲狮 屁颠屁颠去王府请安禀事想必"叛逃"出北凉的严杰溪憋了口恶气难怪他到京城以后成 落や痒霹 绡キ┟ 喇烊嫂可 扣甩 燕文鸾何仲忽这拨春秋老将可不是血气方刚的愣头青听过徐北枳的言论后并未出现太 询ず氯珏 铋屐 纬玮僖湟 即胫呈近 直接跟韩芳碰头哪怕现在接连数次重创后元气大伤的离阳赵勾已经在蓟州不如往昔老军 朦伍邈彀 虎虐苁 润品粜宙 缱秃唛帆 4碑垲耋 谟亡㈡濮 撖掊梃鹩 返训恩 鉤凡灼衛嚴游脖酵堤遗诿登宜松紫 抹怡彼 冶炼鳌邂 箱鲒葺罴 李老头儿揉了揉下巴道:&q

【Spring】从源码分析Spring配置文件的加载

使用Spring必须在web.xml中写如下配置: <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-valu

如何手动获取Spring容器中的bean(ApplicationContextAware 接口)

ApplicationContextAware 接口的作用 先来看下Spring API 中对于 ApplicationContextAware 这个接口的描述: 即是说,当一个类实现了这个接口之后,这个类就可以方便地获得 ApplicationContext 中的所有bean.换句话说,就是这个类可以直接获取Spring配置文件中,所有有引用到的bean对象. 如何使用 ApplicationContextAware 接口 如何使用该接口?很简单. 1.定义一个工具类,实现 Applicati

如何在手动获取spring中的bean(Spring ApplicationContextAware获取上下文)

一.目的 写了一个项目,多个module,然后想在A模块中实现固定的config注入,当B模块引用A时候,能够直接填写相对应的配置信息就行了.但是遇到一个问题,B引用A时候,A的配置信息总是填充不了,获取不到在B中配置好的信息.猜测原因:因为项目的的bean文件没有被统一管理. 二.ApplicationContextAware 接口 Spring 提供了ApplicationContextAware类,通过它可以获取所有bean上下文. 也就是说,当一个类实现了这个接口之后,这个类就可以方便地

SSH框架系列:Spring读取配置文件以及获取Spring注入的Bean

分类: [java]2013-12-09 16:29 1020人阅读 评论(0) 收藏 举报 1.简介 在SSH框架下,假设我们将配置文件放在项目的src/datasource.properties路径下,Spring的配置文件也是src/applicationContext.xml路径下,那么我们可以借助Spring的property-placeholder读取配置文件,然后注入Bean中.我们在程序中,可以根据Bean的Id,获取注入的值.这样我们就可以借助Spring来读取配置文件. 2.

web.xml中配置spring监听器和spring配置文件位置

<!-- spring配置文件位置 --> <context-param>  <param-name>contextConfigLocation</param-name>  <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- spring核心监听器 --> <listener>  <

怎么获取Spring的ApplicationContext

在 WEB 开发中,可能会很少需要显示的获得 ApplicationContext 来得到由 Spring 进行管理的某些 Bean, 今天我就遇到了,在这里和大家分享一下, WEB 开发中,怎么获取 ApplicationContext 一       要想怎么获取 ApplicationContext, 首先必须明白 Spring 内部 ApplicationContext 是怎样存储的.下面我们来跟踪一下源码 首先:从大家最熟悉的地方开始 Java代码   <listener> <

spring-让bean获取spring容器

1.如上一篇文章所述,有时候bean想发布一些容器事件,就需要先获取spring容器,然后将Event交由spring容器将事件发布出去. 为了让bean获取它所在的spring容器,可以让该bean实现BeanFactoryAware接口,BeanFactoryAware接口只有一个方法.  setBeanFactory(BeanFactory beanFactory):beanFactory参数指向创建它的BeanFactory.这个setter方法与我们往常的setter方法的使用有些差别