WEB-INF / myproject-servlet.xml与WEB-INF / web.xml

时间:2014-04-02 08:23:09

标签: java xml spring

我花了几天修复Spring项目中的bug。很长一段时间,错误日志中的主要问题是:

Bean already exists

我有两个文件:

WEB-INF/myproject-servlet.xml
WEB-INF/web.xml

在第一个中,我可以进行以下输入(让我们假设我有一个动物园管理动物的应用程序):

<context:component-scan base-package="com.my.package.animals" />

有了(以及我理解)我们正在启用Spring bean自动发现。所以现在,当我们运行我们的应用程序时,Spring将从该包中获取所有类,稍后它将遍历resources目录中的所有配置文件并初始化所有bean(放置在与给定文件关联的配置文件中)封装)。

第二个,web.xml包含这样的行

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/myproject-servlet.xml</param-value>
</context-param>

我也可以将路径放到我的配置文件中,例如:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:animals-config.xml</param-value>
</context-param>

现在,我在myproject-servlet.xml中进行了“自动检测”,context-param中的web.xml用于相同的对象。

我的问题是,是否有可能错误“Bean已存在”来自于此?我几乎可以肯定是的,我检查了所有豆类ID并且没有重复。

所以我有另一个问题。这样做的好方法是什么?当我创建新的配置文件时,我应该在哪里通知我的应用程序?在myproject-servlet.xmlweb.xml。我真的需要清理我的应用程序,我将从那开始。

我检查了一些示例,而不是在<context-param>Simple example

中放置多个web.xml的人

提前谢谢


好的,我非常接近解决我的问题。

我们假设我有两个包:

com.my.pckg.a
com.my.pckg.b

有课程

com.my.pckg.a.ClassA
com.my.pckg.b.ClassB

我在myproject-servlet.xml后面添加了一行:

<context:component-scan base-package="com.my.pckg.a" />

我有一个配置文件myconfig.xml,里面我有基于 ClassA ClassB 类的bean。

假设我们有以下ID的bean:

ClassA: ida1, ida2
ClassB: idb1, idb2

所以,我正在运行我的码头服务器,问题是:

将初始化哪些bean?我只声明了包com.my.pckg.a,因此从myconfig.xml开始,spring只应加载ida1ida2但是此文件还包含另一个类的bean。

最后......?


最后,我想我发现了一个问题。在web.xml文件中,我有一行:

<context:component-scan base-package="com.dirty.pckg" />

在这个包中,我有一个带DirtyClass注释的课程@Controller。该课程的其中一个领域是:

private static ApplicationContext context = new ClassPathXmlApplicationContext("dirty-config.xml");

所以,当我的应用程序启动时,Spring需要DirtyClass(因为它有@)并映射它。因为os static上下文修饰符会触发读取dirty-config.xml。这是我无法理解为什么我的代码以奇怪的方式表现的方式。

2 个答案:

答案 0 :(得分:1)

web.xml文件是Web应用程序的配置。它与Spring无关。

contextConfigLocation context-param是一个用于搜索Spring配置文件的spring监听器。这与春天有关。

您可以在web.xml中注册多个spring配置文件,但这些文件不能定义相同的bean(bean id必须不同)。您也可以只有一个弹簧配置文件,它将包含其他配置文件,如下所述:http://www.mkyong.com/spring/load-multiple-spring-bean-configuration-file/


回答另一个问题:

当您添加组件扫描时,您要求spring扫描包com.my.pckg.a以获取注释,如@ Service,@ Component,...组件扫描不是其他配置的过滤器,它是一个配置本身。所以你添加组件扫描的事实,不会改变myconfig.xml的行为。 ida1,ida2和idb1,idb2都将被实例化。

我没有真正了解您要使用配置文件完成的任务。也许如果您解释了您的需求,我们可以帮助您为您设置正确的配置。

答案 1 :(得分:0)

web.xml是配置文件。它具有应用程序的类(如侦听器,过滤器,过滤器映射,servlet,servlet映射),资源和配置(如上下文参数,diplayname,错误页面,会话配置)以及Web服务器如何使用它们来处理网络请求。当Web服务器收到对应用程序的请求时,它使用web.xml将请求的URL映射到应该处理请求的代码。

来到web.xml中的内容以及myproject-servlet.xml中应该包含的内容:
1)在Spring中,ApplicationContext可以是分层的。一个ApplicationContext可以有多个子ApplicationContexts,并且只能有一个父。子ApplicationContext中的Bean可以访问父级中的bean。

2)DispatcherServlet通过可配置的处理程序映射,视图解析配置(用于应用程序的视图模板,例如jsp)将请求分派给处理程序(控制器)。

记住这两点,我们的web.xml应该是:

    <!--Root web application context(Parent context) - beans for service or persistence layer should be in this -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:service-layer-beans.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <!--DispatcherServlet loads its configuration into its own context(chile context) and refers Root web application context as a parent, so it have access to beans in parent context and can override it but not vice versa.-->
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/myproject-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>