Understanding Spring Boot Configuration Class Parsing and Core Annotations

Spring Boot parses @SpringBootApplication by combining @SpringBootConfiguration, @EnableAutoConfiguration, and @ComponentScan, then processes @Import, @Conditional, and bean post‑processors, uses SpringFactoriesLoader for auto‑configuration, and follows an eight‑step configuration‑class parsing flow to register beans during startup.

vivo Internet Technology
vivo Internet Technology
vivo Internet Technology
Understanding Spring Boot Configuration Class Parsing and Core Annotations

Spring Boot is a popular Java framework that provides zero‑configuration integration of many third‑party libraries. While it enables rapid development, customizing or extending the framework requires a deep understanding of how Spring Boot parses configuration classes and registers beans.

Basic concepts

The article focuses on Spring Boot 2.1.7.RELEASE and explains how the framework processes configuration classes annotated with @SpringBootApplication. This meta‑annotation is composed of three core annotations:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication { }

@SpringBootConfiguration

It is essentially a @Configuration class, which tells Spring that the class defines bean definitions.

@Configuration
public @interface SpringBootConfiguration { }

@EnableAutoConfiguration

Through @Import it registers AutoConfigurationImportSelector and AutoConfigurationPackages.Registrar, which import auto‑configuration classes.

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration { }

@ComponentScan

Works like <context:component-scan> and scans the package of the main configuration class for components annotated with @Component, @Service, @Repository, etc.

@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

@Import

The article demonstrates custom import mechanisms, such as a user‑defined @EnableAnimal annotation that imports several classes via @Import:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({Dog.class, AnimalRegisterConfiguration.class, AnimalImportSelector.class, AnimalImportBeanDefinitionRegistar.class})
public @interface EnableAnimal { }

Four import styles are covered:

Direct class import ( @Import({Dog.class}))

Configuration class import

ImportSelector implementation

ImportBeanDefinitionRegistrar implementation

@Conditional

Conditional annotations like @ConditionalOnMissingBean control whether a bean is created based on the presence of another bean.

@Bean
@ConditionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver() { }

Custom conditions can be created by implementing Condition and defining a meta‑annotation:

public class MyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String[] value = (String[]) metadata.getAnnotationAttributes(MyConditionAnotation.class.getName()).get("value");
        for (String property : value) {
            if (StringUtils.isEmpty(context.getEnvironment().getProperty(property))) {
                return false;
            }
        }
        return true;
    }
}

@Conditional(MyCondition.class)
public @interface MyConditionAnotation {
    String[] value() default {};
}

SpringFactoriesLoader

Spring Boot uses a SPI‑like mechanism to load auto‑configuration classes from META-INF/spring.factories. The loader reads the properties file and returns a list of class names for a given key (e.g., EnableAutoConfiguration).

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}

Bean post‑processing

The article shows examples of BeanFactoryPostProcessor and BeanPostProcessor implementations that add or modify bean definitions before and after bean instantiation.

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(Chicken.class);
        registry.registerBeanDefinition("beanFactoryPostProcessor-Chicken", beanDefinition);
        BeanDefinition snake = registry.getBeanDefinition("snake");
        snake.setLazyInit(true);
    }
}

@Component
public class CatBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof Cat) {
            ((Cat) bean).setName("changeNameCat");
        }
        return bean;
    }
}

Spring Boot startup flow

The article outlines the bootstrapping steps, highlighting that during refreshContext the fifth step invokes postProcessBeanDefinitionRegistry of ConfigurationClassPostProcessor. This processor parses configuration classes, registers bean definitions, and handles imports, property sources, component scans, and conditional logic.

Configuration class parsing process

The parsing consists of eight sub‑steps:

Detect if a class is a configuration candidate.

Process member (nested) classes.

Handle @PropertySource annotations.

Handle @ComponentScan annotations.

Handle @Import annotations (including ImportSelector and ImportBeanDefinitionRegistrar).

Handle @ImportResource (XML) annotations.

Process individual @Bean methods.

Process default methods on interfaces and superclass hierarchy.

Each step is illustrated with code excerpts and explanations of how Spring builds ConfigurationClass objects, resolves imports, and ultimately registers bean definitions into the application context.

Deferred import selectors and auto‑configuration

Auto‑configuration is performed by a DeferredImportSelector ( AutoConfigurationImportSelector) that loads candidate classes from spring.factories, applies exclusions and filters, and finally registers the selected auto‑configuration classes.

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    }
    List<String> configurations = getCandidateConfigurations(annotationMetadata, getAttributes(annotationMetadata));
    configurations = filter(configurations, autoConfigurationMetadata);
    return new AutoConfigurationEntry(configurations, exclusions);
}

After parsing, ConfigurationClassPostProcessor calls loadBeanDefinitions to register beans defined by configuration classes, @Bean methods, imported resources, and registrars.

In summary, the article provides a comprehensive walkthrough of how Spring Boot discovers, parses, and registers configuration classes, covering core annotations, import mechanisms, conditional processing, and the auto‑configuration infrastructure.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaConfigurationSpring Bootannotationsdependency-injectionauto-configurationBean Processing
vivo Internet Technology
Written by

vivo Internet Technology

Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.