11

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

让我从描述我的设置开始。一、简单的数据对象

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

还有一个测试班。。

@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();
    }
}

突然间,当需要构造bean时,该@Autowired对象为空。confApple

更奇怪的是,如果我将CustomScopeConfigurerbean 移到TestConfig课堂上,那么它就可以工作。

CustomScopeConfigurer关于范围或对象,我有什么不知道的吗?

4

1 回答 1

19

从 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 级别的日志消息。

于 2013-02-18T18:37:38.727 回答