Spring Framework
  1. Spring Framework
  2. SPR-1142

Load files in <import resource=.../> only once

    Details

    • Last commented by a User:
      true

      Description

      Example:

      file1.xml:
      <beans>
      <import resource="classpath:common/common-config.xml"/>
      ...
      </beans>

      file2.xml:
      <beans>
      <import resource="classpath:common/common-config.xml"/>
      ...
      </beans>

      If I load now an application context which has "file1.xml" and "file2.xml" as config locations, the file "common-config.xml" will be loaded twice. I suggest to remember the url of already loaded config files.

      Thanks,
      Martin

        Issue Links

          Activity

          Hide
          Sébastien Launay added a comment -

          Because this issue is opened for many years I was thinking of proposing a solution because our spring configuration uses lots of XML files decomposed with imports and lots of AOP configuration and computing unused bean definitions is expensive at runtime.

          So here is a patch for loading application context resources only once against the trunk.
          It contains:

          • modification to keep a list of previously imported resource URLs in order to know if this is an already imported resource (if this is the case it is ignored with an INFO log entry)
          • test cases
          • a paragraph in the reference documentation

          This feature is enabled by setting the bean property importOnce to true on *XmlApplicationContext.
          This property is false by default for backward compatibility purpose.

          I do not know if this is interesting but I do not modified JavaConfig classes to reflect such behavior with @Import.

          Let me know if this approach is right or if I need to go in another direction.

          Show
          Sébastien Launay added a comment - Because this issue is opened for many years I was thinking of proposing a solution because our spring configuration uses lots of XML files decomposed with imports and lots of AOP configuration and computing unused bean definitions is expensive at runtime. So here is a patch for loading application context resources only once against the trunk. It contains: modification to keep a list of previously imported resource URLs in order to know if this is an already imported resource (if this is the case it is ignored with an INFO log entry) test cases a paragraph in the reference documentation This feature is enabled by setting the bean property importOnce to true on *XmlApplicationContext . This property is false by default for backward compatibility purpose. I do not know if this is interesting but I do not modified JavaConfig classes to reflect such behavior with @Import . Let me know if this approach is right or if I need to go in another direction.
          Hide
          Tim Ducheyne added a comment -

          Just a small remark about the patch:
          I think it would be better to use URIs instead of URLs

          There is a problem with the hashcode and equals implementation of URL
          http://michaelscharf.blogspot.com/2006/11/javaneturlequals-and-hashcode-make.html

          brgds,
          Tim

          Show
          Tim Ducheyne added a comment - Just a small remark about the patch: I think it would be better to use URIs instead of URLs There is a problem with the hashcode and equals implementation of URL http://michaelscharf.blogspot.com/2006/11/javaneturlequals-and-hashcode-make.html brgds, Tim
          Hide
          Felix Simmendinger added a comment -

          This behaviour is espacially then problematic, because BPP are executed multiple times if they are declared as anonymous beans or defined via a namespace eg. <context:property-placeholder ... . For the latter it is impossible to define an id. Since there are special beans that can be defined only once eg. the multipartresolver this problem means you cannot hide the multipartresolver in a xml file hierarchy as it may be loaded twice.

          Show
          Felix Simmendinger added a comment - This behaviour is espacially then problematic, because BPP are executed multiple times if they are declared as anonymous beans or defined via a namespace eg. <context:property-placeholder ... . For the latter it is impossible to define an id. Since there are special beans that can be defined only once eg. the multipartresolver this problem means you cannot hide the multipartresolver in a xml file hierarchy as it may be loaded twice.
          Hide
          Dennis Homann added a comment -

          This is a real pain and punishes people who modularize their application context in multiple smaller XML files.
          Please consider fixing this issue in 3.1 instead of 3.2.

          Show
          Dennis Homann added a comment - This is a real pain and punishes people who modularize their application context in multiple smaller XML files. Please consider fixing this issue in 3.1 instead of 3.2.
          Hide
          Keith Donald added a comment -

          Can someone provide more info on why you would import the same file more than once? I'm curious what is trying to be accomplished where this comes up, as I've never encountered this myself in practice.

          Show
          Keith Donald added a comment - Can someone provide more info on why you would import the same file more than once? I'm curious what is trying to be accomplished where this comes up, as I've never encountered this myself in practice.
          Hide
          Dale Wyttenbach added a comment -

          It typically happens indirectly:
          A imports B imports C
          A imports D imports C
          It's an old problem, in C the #ifndef directive was used in similar situations.
          I have opened a related issue SPR-7607, which I think would make the log messages a lot easier
          to interpret in these situations.

          Show
          Dale Wyttenbach added a comment - It typically happens indirectly: A imports B imports C A imports D imports C It's an old problem, in C the #ifndef directive was used in similar situations. I have opened a related issue SPR-7607 , which I think would make the log messages a lot easier to interpret in these situations.
          Hide
          Andy Schäfer added a comment -

          Some additional thoughts to the comment of Dale Wyttenbach in answer to Keith Donald:

          In order to ensure, that C isn't loaded twice we import in the topmost application.spring.xml all configurations (A, B, C and D). So the import of C is done only there, nowhere else.
          Problem solved but other problems arise with this approach:

          1) Design-flaw: dependencies between configurations aren't expressed explicitly

          2) Running Tests: In order to run tests concerning for example B we had to load the configuration of B and C. Assumed C gets a dependency to a new configuration-file E, ALL tests of A,B,C AND D had to be changed. Instead we load the complete application-context for our tests. But now D and A are unnecessarily loaded for our B-test -> turnaround time increases.

          Maybe there are approaches better than the one I outlined (interested to hear of them), but this issue would be handy to solve the problem in a simple way:

          1) dependencies can be expressed explicitly (e.g. B imports C)
          2) Each test had to load only the configuration of it's own module - dependent configurations are loaded transparently

          Show
          Andy Schäfer added a comment - Some additional thoughts to the comment of Dale Wyttenbach in answer to Keith Donald: In order to ensure, that C isn't loaded twice we import in the topmost application.spring.xml all configurations (A, B, C and D). So the import of C is done only there, nowhere else. Problem solved but other problems arise with this approach: 1) Design-flaw: dependencies between configurations aren't expressed explicitly 2) Running Tests: In order to run tests concerning for example B we had to load the configuration of B and C. Assumed C gets a dependency to a new configuration-file E, ALL tests of A,B,C AND D had to be changed. Instead we load the complete application-context for our tests. But now D and A are unnecessarily loaded for our B-test -> turnaround time increases. Maybe there are approaches better than the one I outlined (interested to hear of them), but this issue would be handy to solve the problem in a simple way: 1) dependencies can be expressed explicitly (e.g. B imports C) 2) Each test had to load only the configuration of it's own module - dependent configurations are loaded transparently
          Hide
          Neha added a comment -

          Since this issue had been logged around 9 years back and is still unresolved, I was just wondering if there is some major reason for it?
          We were thinking of including our own classes in our project to handle this problem, so wanted to know if there is possibility of some side-effects, before moving the code to production?

          Show
          Neha added a comment - Since this issue had been logged around 9 years back and is still unresolved, I was just wondering if there is some major reason for it? We were thinking of including our own classes in our project to handle this problem, so wanted to know if there is possibility of some side-effects, before moving the code to production?

            People

            • Assignee:
              Juergen Hoeller
              Reporter:
              Martin Zeltner
              Last updater:
              Juergen Hoeller
            • Votes:
              54 Vote for this issue
              Watchers:
              42 Start watching this issue

              Dates

              • Created:
                Updated:
                Days since last comment:
                7 weeks, 1 day ago