skip to content

What does @ImportResource do and when would you use it?

level: middleimportance: should knowfreq 30%

answer

  1. XML bridge into Java config
  2. takes resource locations, not classes
  3. XmlBeanDefinitionReader / Groovy by extension
  4. migration / legacy / third-party XML
  5. coexists with @Import

basics

~10 s

@ImportResource loads bean definitions from external resource files — typically XML — into a Java @Configuration class. You point it at locations like "classpath:legacy-beans.xml", and those beans join the same context.

solid answer

~40 s

@ImportResource is placed on a @Configuration class and imports bean definitions from resource files (XML by default, Groovy DSL if the file ends .groovy) into the annotation-driven context. Its value/locations attribute takes Spring resource strings such as "classpath:beans.xml". Beans defined in that XML become first-class members of the same ApplicationContext, so they can be autowired into @Bean methods and vice-versa. You use it mainly to bridge legacy XML configuration into a modern Java-config app during migration, or to consume a third-party module that only ships XML. It differs from @Import, which takes Java classes; @ImportResource takes resource locations and delegates to an XmlBeanDefinitionReader (or Groovy reader) chosen by file extension.

code

java · 10 lines
java
@Configuration
@ImportResource({ "classpath:legacy-beans.xml" })
public class BridgeConfig {

    // A Java-config bean can autowire a bean declared in the XML file
    @Bean
    OrderService orderService(LegacyPricingBean pricing) {
        return new OrderService(pricing);
    }
}

go deeper

for a junior

Know it pulls XML-defined beans into a Java @Configuration app.

for a middle

Explain it takes resource locations, picks a reader by extension, and merges into the same context; contrast with @Import.

for a senior

Discuss migration strategy, placeholder resolution, and why Boot steers away from it.

for a principal

Position it as a controlled legacy-interop seam and reason about profile/condition scoping living inside the XML rather than the annotation.

**@ImportResource** (`org.springframework.context.annotation.ImportResource`) is a type-level annotation for a `@Configuration` class that loads *externally defined* bean definitions — most commonly classic Spring **XML** — and merges them into the same annotation-driven `ApplicationContext`. **Why it exists:** `@Import` only accepts Java `Class<?>` references, so it cannot pull in beans that are described in XML. Before Java config, applications defined beans in XML (`<bean id="..." class="..."/>`). When teams migrated to `@Configuration`/`@Bean`, they still needed to consume that legacy XML (or XML shipped by a third-party library). `@ImportResource` is the bridge. **How it works:** - The `value` (alias `locations`) attribute is an array of **Spring resource location strings**, e.g. `"classpath:legacy-context.xml"`, `"classpath*:META-INF/spring/*.xml"`, or `"file:/etc/app/beans.xml"`. - The optional `reader` attribute lets you specify a `BeanDefinitionReader`. If omitted, Spring picks one by extension: `.xml` → `XmlBeanDefinitionReader`, `.groovy` → `GroovyBeanDefinitionReader`. - The XML's `<bean>` definitions are parsed and registered in the very same registry as your `@Bean` methods, so wiring crosses freely: an XML bean can be `@Autowired` into a `@Bean` method, and an XML `<bean>` can reference a Java-config bean by name via `ref`. **Example flow:** annotate the config class with `@ImportResource("classpath:legacy-beans.xml")`; at startup the `ConfigurationClassPostProcessor` sees it and loads those definitions. **Edge cases & gotchas:** - **Not for Java classes** — passing a class won't compile; use `@Import` for classes and `@ImportResource` for resource files. They can coexist on the same config class. - **Property placeholders** in the XML still need a `PropertySourcesPlaceholderConfigurer` / `@PropertySource` available in the context to resolve `${...}`. - **Profiles/conditions** don't gate the XML file itself; put `<beans profile="...">` inside the XML if you need profile scoping there. - **Spring Boot** discourages XML — Boot's guidance is Java config only — but `@ImportResource` still works if you must consume legacy XML. - It loads *bean definitions*, not arbitrary config; you can't point it at a `.properties` file (use `@PropertySource` for that). **When to use:** legacy-XML migration, consuming a library that only offers XML wiring, or teams that still keep some declarative XML. In greenfield Java/Kotlin apps you should not need it.

  • Can a bean defined in @ImportResource XML be injected into a @Bean method, and vice versa?
    Yes. XML and Java-config definitions land in the same BeanDefinitionRegistry / ApplicationContext, so wiring is bidirectional: @Autowire XML beans into @Bean methods, and reference Java-config beans from XML via ref by bean name.

saying these in an interview costs you the question

  • Using @ImportResource to load a .properties file (that's @PropertySource)
  • Passing a @Configuration class to @ImportResource instead of @Import
  • Believing XML beans live in a separate context and can't wire with Java beans

context