Spring Boot初始化前手动注入@Configuration类并注册Bean的方法
你遇到的问题核心是:直接用GenericBeanDefinition注册ManualConfiguration时,Spring只把它当成普通Bean,不会识别类上的@Configuration注解,自然不会解析内部的@Bean方法生成Car实例。要实现类似@Import的效果,得让Spring把这个类当作配置类来处理。
最简单的解决方案:用AnnotatedGenericBeanDefinition注册
AnnotatedGenericBeanDefinition会保留类的注解元数据,Spring的ConfigurationClassPostProcessor会自动识别到@Configuration注解,进而解析内部的@Bean方法。修改你的Processors类即可:
@Component public class Processors implements BeanDefinitionRegistryPostProcessor{ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("postProcessBeanFactory -> "+beanFactory); } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { System.out.println("postProcessBeanDefinitionRegistry -> "+registry); // 替换为AnnotatedGenericBeanDefinition,保留类的注解信息 AnnotatedGenericBeanDefinition bd = new AnnotatedGenericBeanDefinition(ManualConfiguration.class); registry.registerBeanDefinition("manualCarLoading", bd); } }
这样修改后,Spring会识别ManualConfiguration为配置类,自动解析里面的car()方法,生成Car的Bean实例,你在main方法中就能成功获取到Car Bean。
原理说明
GenericBeanDefinition是最基础的BeanDefinition实现,只记录了Bean的类信息,没有保留注解元数据。而AnnotatedGenericBeanDefinition会封装类上的所有注解(包括@Configuration),当Spring的配置类处理器扫描到这个BeanDefinition时,会判断它带有@Configuration注解,然后触发内部@Bean方法的解析和Bean实例的创建,这和@Import注解的处理逻辑一致。
其他可选方案
如果需要更灵活的控制,也可以手动调用ConfigurationClassPostProcessor来处理配置类,但这种方法相对复杂,一般没必要。另外,如果场景允许,直接在@SpringBootApplication上添加@Import(ManualConfiguration.class)是最便捷的方式,但这不符合你通过BeanDefinitionRegistryPostProcessor手动注册的需求。
内容的提问来源于stack exchange,提问作者danipenaperez

