Spring的JavaConfig和CustomScopeConfigurer问题

我看到一些奇怪的行为,我希望这里有人可以对这个问题有所了解。

我先来描述一下我的设置。 首先,一个简单的数据对象

public class Apple { private String name; public Apple withName(String name) { this.name = name; return this; } public String getName() { return name; } } 

还有一个测试class..

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes={TestConfig.class}) public class AppleTest { @Autowired private Apple apples; @Test public void simpleTest() { System.out.println("OBJ: "+apples); } } 

配置如下

 @Configuration public interface ConfigInterface { public Apple getApple(); } 

有一个实施类

 @Configuration @Import(AbstractTestConfig.class) public class TestConfig implements ConfigInterface { public Apple getApple() { return new Apple().withName("Granny apples"); } } 

使用配置依赖…

 @Configuration public class AbstractTestConfig { @Autowired ConfigInterface conf; @Bean Apple myTestApple() { return conf.getApple(); } } 

所有这些都很棒。 我运行测试,我看到了我期望的输出。 但后来我将一个扳手扔到方向盘上并修改AbstractTestConfig,如下所示。

 @Configuration public class AbstractTestConfig { @Autowired ConfigInterface conf; @Bean Apple myTestApple() { return conf.getApple(); } // NEW CODE @Bean CustomScopeConfigurer scopeConfigurer() { return new CustomScopeConfigurer(); } } 

当需要构造Apple bean时,@ @Autowired对象conf突然变为null。

更奇怪的是,如果我将CustomScopeConfigurer bean移动到TestConfig类,那么它可以工作。

是否有我不了解的范围或者特别是CustomScopeConfigurer对象?

从Spring @Bean javadoc复制:

BeanFactoryPostProcessor-返回@Bean方法

必须特别考虑返回Spring BeanFactoryPostProcessor(BFPP)类型的@Bean方法。 由于BFPP对象必须在容器生命周期的早期实例化,因此它们可能会干扰@Configuration类中@Autowired,@ Value和@PostConstruct等注释的处理。 要避免这些生命周期问题,请将BFPP返回@Bean方法标记为静态。 例如:

 @Bean public static PropertyPlaceholderConfigurer ppc() { // instantiate, configure and return ppc ... } 

通过将此方法标记为静态,可以调用它而不会导致其声明@Configuration类的实例化,从而避免上述生命周期冲突。 但请注意,如上所述,静态@Bean方法不会针对作用域和AOP语义进行增强。 这在BFPP案例中有效,因为它们通常不被其他@Bean方法引用。 提醒一下,将为任何具有可分配给BeanFactoryPostProcessor的返回类型的非静态@Bean方法发出WARN级别的日志消息。