Understanding Spring Boot Auto‑Configuration and Bean Definition Mechanisms
This article provides a comprehensive tutorial on Spring Boot's auto‑configuration process, covering bean injection styles, XML and JavaConfig configurations, BeanDefinition internals, autowire modes, constructor argument handling, custom BeanFactoryPostProcessor usage, @Import mechanisms, and the inner workings of Spring Boot's EnableAutoConfiguration and its loading of META‑INF/spring.factories.
1. Introduction
The author introduces Spring Boot's core concept of automatic configuration and explains why mastering bean auto‑wiring is essential for Spring Boot beginners.
2. Warm up – Bean injection basics
Three classic bean injection methods are demonstrated with a simple Person class using Lombok annotations.
/**
* @author dzzhyk
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
private Boolean sex;
}Examples of setter injection, constructor injection, and annotation‑based property injection are shown with corresponding XML configuration and JUnit test classes.
<!-- 手动配置bean对象 -->
<bean id="person" class="pojo.Person">
<property name="name" value="dzzhyk"/>
<property name="age" value="20"/>
<property name="sex" value="true"/>
</bean> public class TestVersion1 {
@Test
public void test(){
ApplicationContext ca = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = ca.getBean("person", Person.class);
System.out.println(person);
}
}3. XML vs JavaConfig
The article contrasts XML‑based bean definitions with Java‑based @Configuration classes, showing how the same Person bean can be defined in both ways.
@Configuration
@ComponentScan
public class PersonConfig {
@Bean
public Person person(Dog dog, Car car){
return new Person("dzzhyk", 20, true, dog, car);
}
@Bean
public Dog dog(){
return new Dog("旺财", 5);
}
@Bean
public Car car(){
return new Car("奥迪双钻", 100000);
}
}4. BeanDefinition internals
The author dives into Spring's AbstractBeanDefinition, focusing on three key fields: beanClass, autowireMode, and constructorArgumentValues.
private volatile Object beanClass;
private int autowireMode = AUTOWIRE_NO;
private ConstructorArgumentValues constructorArgumentValues;4.1 beanClass
Changing the bean class at runtime via a custom BeanFactoryPostProcessor is demonstrated.
public class MyBeanPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition defA = (GenericBeanDefinition) beanFactory.getBeanDefinition("a");
System.out.println("这里是MyBeanPostProcessor,我拿到了:" + defA.getBeanClassName());
// Change class from A to B
defA.setBeanClass(B.class);
}
}4.2 autowireMode
By setting autowireMode to AUTOWIRE_BY_NAME, the author shows that a dependency can be injected without the @Autowired annotation.
defA.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);4.3 constructorArgumentValues
Using ConstructorArgumentValues the author forces Spring to use a specific constructor.
ConstructorArgumentValues args = new ConstructorArgumentValues();
args.addIndexedArgumentValue(0, "我指定的姓名");
args.addIndexedArgumentValue(1, 20);
defStu.setConstructorArgumentValues(args);5. Custom @Import mechanisms
The article explains three ways to import beans: direct class import, ImportBeanDefinitionRegistrar, and ImportSelector. A custom selector reads a properties file to decide which configuration class to load.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportSelector.class)
public @interface MyEnableAutoConfig {} public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
Properties properties = MyPropertyReader.readPropertyForMe("/MyProperty.properties");
String className = (String) properties.get(MyEnableAutoConfig.class.getName());
return new String[]{className};
}
}6. Spring Boot’s own auto‑configuration
Spring Boot’s @EnableAutoConfiguration works exactly like the custom selector: it imports AutoConfigurationImportSelector, which reads META-INF/spring.factories to obtain a list of configuration classes.
static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";The loader caches the parsed factories to avoid repeated I/O.
if (result != null && !result.isEmpty()) {
return result;
}
// load and cache logic follows7. Summary of the auto‑configuration process
1) @SpringBootApplication combines @SpringBootConfiguration, @EnableAutoConfiguration, and @ComponentScan. 2) @EnableAutoConfiguration imports AutoConfigurationImportSelector. 3) The selector reads spring.factories to get candidate configuration class names. 4) Duplicates are removed and user‑specified exclusions are applied. 5) All selected configuration classes are registered as beans, completing the automatic wiring of the application context.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
