2010-07-14 83 views
4

假設我們有一個簡單的@Configuration如何使用@Configuration的現有實例創建註釋配置的bean?

@Configuration 
public class FooBarConfiguration { 

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

    @Bean 
    @Autowired 
    public Bar createBar(Foo foo) { 
     return new BarImpl(foo); 
    } 
} 

這個類可以與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()); 

在上面春天的例子將創建FooBarConfiguration一個新實例,用它來製作Foos和酒吧。

現在假設我們已經有一個實例FooBarConfiguration,我們希望通過Spring創建FOOS和酒吧,這種非常情況下。有沒有辦法做到這一點?

如何用配置對象的現有實例創建註釋配置的bean?


ps。隨着谷歌吉斯的解決方案很簡單:

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()); 
+0

您不需要'create_ar'上的'@ Inject'註釋。 – whiskeysierra 2010-07-14 22:02:49

+0

對!以及Spring中的@Autowired示例。我比較新的基於註釋的配置,我主要是一個硬核舊的Spring XML配置的傢伙。 :) – lexicore 2010-07-14 22:12:44

+0

爲什麼您需要使用配置類的現有實例而不是新配置?也許有另一種方式來達到你的目標... – meriton 2010-07-24 14:29:48

回答

2

這是不可能的,因爲Spring的@Configuration的一些功能需要增強類,即無法在現有的實例來完成。

例如,你可以重寫你的配置如下:

@Configuration 
public class FooBarConfiguration { 

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

    @Bean 
    public Bar createBar() { 
     return new BarImpl(createFoo()); 
    } 
} 

,你仍然會得到Foo一個完全初始化實例,因爲調用createFoo()將被攔截。

+0

我真的不明白爲什麼直接模擬在Guice中不可行。我對某些功能無法正常工作很好,但是一般的事情「這裏是帶有註釋類的實例,使應用程序環境脫離它們」必須是可能的。 – lexicore 2010-07-14 22:16:56

2

這是我自己的變種:

@Test 
    public void createFromConfigurationInstance() { 

     final FooBarConfiguration fooBarConfiguration = new FooBarConfiguration(); 

     final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); 

     final AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(
       beanFactory); 

     annotatedBeanDefinitionReader.register(FooBarConfiguration.class); 

     beanFactory.registerSingleton("fooBarConfiguration", 
       fooBarConfiguration); 

     final ConfigurableApplicationContext applicationContext = new GenericApplicationContext(
       beanFactory); 

     applicationContext.refresh(); 

     final Foo foo = applicationContext.getBean(Foo.class); 
     final Bar bar = applicationContext.getBean(Bar.class); 
     assertSame(foo, bar.getFoo()); 

    } 

不過,我不知道這是否是一個「好」或「官方」的方式。

0

在春天你基本上要麼:

  1. 迫使你FooBarConfiguration是 一個Singleton(不依靠IoC的 容器上執行本 - 如 實現使用枚舉,或其他 Singleton模式)

  2. 將您的FooBarConfiguration包裝在FooBarConfigurationFactory中,並使用類似MethodInvokingFactoryBean的東西來調用它。

  3. 直接在FooBarConfiguration上公開一個靜態工廠方法,並使用與#2相同的技術。

+0

1.在使用java-based-config時,Spring不支持配置類。 2.你的方法如何調用工廠bean知道使用哪個工廠?你將如何使Spring在創建工廠的Config中創建bean? – meriton 2010-07-24 14:34:08

相關問題