Printemps annotations - @Configuration pour appeler le printemps bean auto-construction

Si je déclare une classe à l'aide de @Bean et le composant d'analyse pour la classe, le printemps va instancier la classe en appelant son constructeur et de l'injection constructeur args et l'injection de tout les champs marqués avec @Inject. Pour simplifier, appelons ce printemps de l'auto-construction.

Je n'aime pas le composant d'analyse et souhaitez l'éviter complètement (je ne souhaite pas discuter de mes raisons pour ne pas l'aimer). Je voudrais utiliser un @Configuration de l'objet au lieu de cela, mais serait tout de même avoir l'auto-construction fonctionnalité disponible pour moi. Est-il possible d'invoquer printemps à l'auto-construire mes objets au lieu de devoir explicitement à passer tous les arguments du constructeur dans ma @Configuration de l'objet?

Permet de supposer que j'ai un haricot:

public class MyServiceImpl implements MyService {
    public MyServiceImpl(Dependency1 d1, Dependency d2) { ... }
    ....
}

Je pourrais définir un objet de configuration comme ceci:

@Configuration
public class MyConfiguration {
    //lets assume d1 and d2 are defined in another @Configuration
    @Inject
    Dependency1 d1; 

    @Inject
    Dependency2 d2;

    @Bean
    public MyService myService() { 
        //I dislike how I have to explicitly call the constructor here
        return new MyServiceImpl(d1, d2);
    }
}

Mais maintenant, j'ai explicitement dû appeler le MyServiceImpl constructeur de moi-même si je vais devoir garder la mise à jour de ce que mon constructeur changements au fil du temps.

J'espérais que je pourrais déclarer une méthode abstraite, de sorte que le printemps de l'auto-construction ne peut avoir lieu:

@Configuration
public abstract class MyConfiguration {
    @Bean
    public abstract MyServiceImpl myService();
}

Mais cela ne fonctionne pas. Est-il possible que je peux invoquer le printemps de construction automatique de sans l'aide d'un composant d'analyse?

Dans Google Guice, cela peut être fait via le Classeur:
https://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Binder.html

Dans la Tapisserie du CIO, ce qui peut être fait via le ServiceBinder:
http://tapestry.apache.org/ioc-cookbook-basic-services-and-injection.html#IoCCookbook-BasicServicesandInjection-SimpleServices

Mise à jour

Basé sur spod réponse, j'ai pu obtenir ce que je recherchais (merci!). Cas de Test inclus pour toute personne qui veut faire la même chose:

import java.util.Date;
import javax.inject.Inject;
import junit.framework.Assert;
import org.junit.Test;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class AutoBuildConfigurationTest {
@Configuration
public static class MyConfiguration {
@Inject
private AutowireCapableBeanFactory beanFactory;
@Bean
public Date date() {
return new Date(12345);
}
@Bean
public MyService myService() {
return autoBuild(MyService.class);
}
protected <T> T autoBuild(Class<T> type) {
return type.cast(beanFactory.createBean(type, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true));
}
}
public static class MyService {
private Date date;
public MyService(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
}
@Test
public void testAutoBuild() {
ApplicationContext appContext = new AnnotationConfigApplicationContext(MyConfiguration.class);
MyService myService = appContext.getBean(MyService.class);
Assert.assertEquals(12345, myService.getDate().getTime());
}
}

OriginalL'auteur lance-java | 2012-11-27