Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Import registers non-@Component beans

I have noticed that even classes not annotated with @Component are registered into the Spring context when they are declared in the @Import annotation.

@Configuration
@Import({MyBean.class})
class MyConfig {
    @Bean
    Object object(MyBean myBean) { // this works
        return new Object();
    }
}

class MyBean {} // no annotation here

This behavior is not very clear from the @Import documentation.

Is this wanted? Is it documented somewhere? Are there any differences between importing a non-@component and a @Component class?

The documentation says:

Allows for importing @Configuration classes, ImportSelector and ImportBeanDefinitionRegistrar implementations, as well as regular component classes

What is a "regular component class"? Any class or a class annotated with @Component?

like image 385
ttulka Avatar asked Sep 14 '25 00:09

ttulka


1 Answers

Summary

The @Import annotation is designed to turn the referenced classes into bean definitions. If a "regular" component is imported with @Import, there is usually no reason to annotate it with @Component as this annotation does not prescribe any kind of behavior for the resulting bean. @Component does not primarily mark classes as Spring beans but as classes to be picked up by classpath scanning.

Usually, the imported classes are configuration classes that are annotated with @Configuration. And the configuration classes will also be included in the final application context as beans. The word "regular" in this context is meant to refer to beans (or components) that are not also configuration classes or other kinds of beans that add themselves other bean definitions to the application context. The word "regular" here could also be replaced with e.g. "normal" or "plain-vanilla".

In fact, configuration classes that are imported with @Import also don't need to be annotated with @Configuration. But in this case, there is a functional difference as the beans from the @Bean annotated factory methods will be produced in "bean lite" mode if the annotation @Configuration is missing.

Details

The annotation @Component does not describe any kind of behavior of the beans that are instances of the annotated class. It is really just a marker for classes. If classpath scanning is used to configure the application context, then any class annotated with @Component will be turned into a bean definition that will yield a bean that is an instance of the annotated class.

This is also stated in the javadoc of the annotation:

Indicates that an annotated class is a "component". Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning.

Today, annotation-based configuration and classpath scanning are the dominant way today to configure Spring application contexts. This wasn't true in the past, which also saw e.g. a lot of XML configuration. In fact, the Spring framework is older than Java 5, which was the first Java that introduced annotations to the language.

If annotation-based configuration is used but not classpath scanning, the annotation @Import allows to create references from central configuration classes to other configuration classes or in particular "regular" component classes. This is also how the reference documentation talks about this feature:

As of Spring Framework 4.2, @Import also supports references to regular component classes, analogous to the AnnotationConfigApplicationContext.register method. This is particularly useful if you want to avoid component scanning, by using a few configuration classes as entry points to explicitly define all your components.

So if classpath scanning is not used, then there is basically no point in marking classes with @Component as it does not prescribe any behavior. This is not only true for "regular" beans that are imported with @Import but also for beans that come from <bean> elements in an XML configuration or functionally registered beans.

Before Spring 4.2 the annotation @Import could only import non-regular beans like e.g. @Configuration classes. This was because @Import can be thought of as the equivalent of the <import> element in XML configuration, which is used to include e.g. other XML files that then again contain <bean> elements.

The word "regular" in this context refers to classes that I would normally annotate with @Component if classpath scanning were used. The word is only used here to differentiate such classes from "non-regular" components like @Configuration classes, ImportSelector and ImportBeanDefinitionRegistrar implementations.

like image 104
Henning Avatar answered Sep 15 '25 16:09

Henning