如何使用现有的@Configuration 实例创建注解配置的 bean?

lex*_*ore 5 spring annotations dependency-injection guice

假设我们有一个简单的@Configuration

@Configuration
public class FooBarConfiguration {

    @Bean
    public Foo createFoo() {
        return new FooImpl();
    }

    @Bean
    @Autowired
    public Bar createBar(Foo foo) {
        return new BarImpl(foo);
    }
}
Run Code Online (Sandbox Code Playgroud)

此类可用于AnnotationConfigApplicationContext生产FooBar实例:

final ApplicationContext applicationContext =
    new AnnotationConfigApplicationContext(FooBarConfiguration.class);

final Foo foo = applicationContext.getBean(Foo.class);
final Bar bar = applicationContext.getBean(Bar.class);
assertSame(foo, bar.getFoo());
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,Spring 将创建一个新实例FooBarConfiguration并使用它来生成 Foos 和 Bars。

现在假设我们已经有一个实例FooBarConfiguration并且我们想通过 Spring 使用这个实例创建 Foos 和 Bars 。有没有办法做到这一点?

如何使用配置对象的现有实例创建注释配置的 bean ?


附:使用 Google Guice,解决方案很简单:

public class FooBarConfiguration implements Module {

    @Provides
    @Singleton
    public Foo createFoo() {
        return new FooImpl();
    }

    @Override
    public void configure(Binder binder) {
    }

    @Provides
    @Inject
    @Singleton
    public Bar createBar(Foo foo) {
        return new BarImpl(foo);
    }
}

final FooBarConfiguration fooBarConfiguration = ...; // Our instance

final Injector injector = Guice.createInjector(fooBarConfiguration);
final Foo foo = injector.getInstance(Foo.class);
final Bar bar = injector.getInstance(Bar.class);
assertSame(foo, bar.getFoo());
Run Code Online (Sandbox Code Playgroud)

axt*_*avt 2

这是不可能的,因为 Spring 的某些功能@Configuration需要类增强,而这无法在现有实例上完成。

例如,您可以按如下方式重写配置:

@Configuration 
public class FooBarConfiguration { 

    @Bean 
    public Foo createFoo() { 
        return new FooImpl(); 
    } 

    @Bean 
    public Bar createBar() { 
        return new BarImpl(createFoo()); 
    } 
} 
Run Code Online (Sandbox Code Playgroud)

并且您仍然会得到一个完全初始化的实例Foo,因为对的调用createFoo()将被拦截。