Spring annotations - @ Configuration to call Spring bean auto build

If I declare a class using @ Bean and then scan the components for the class, spring will instantiate the class by calling its constructor and inserting the args constructor and entering any fields marked with @Inject. For simplicity, call this spring autocreation.

I don’t like component analysis and I want to completely avoid it (I don’t want to discuss my reasons in order not to like it). Instead, I would like to use the @Configuration object, but I would still like the auto-creation features to be available to me. Is it possible to call spring to automatically build my objects, and not to explicitly pass all the constructor arguments in my @Configuration object?

Suppose I have a bean:

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

I could define a configuration object as follows:

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

But now I clearly had to call the MyServiceImpl constructor, so I have to constantly update it, as it changes the constructor over time.

I was hoping I could declare an abstract method so that spring auto-creation could take place:

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

But that does not work. Is there any way that spring auto build can be called without ?

In Google Guice, this can be done through Binder: https://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Binder.html

In Tapestry IOC, this can be done through the ServiceBinder: http://tapestry.apache.org/ioc-cookbook-basic-services-and-injection.html#IoCCookbook-BasicServicesandInjection-SimpleServices

Update

Based on the answer to the method, I was able to achieve what happened after (thanks!). A test case is included for those who want to do the same:

 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()); } } 
+4
source share
1 answer

The java-based container configuration is independent of component scanning. This is just another approach for configuring XML-based components. With an XML configuration, you just need to declare your bean using the MyServiceImpl class if its @inject is already annotated. Spring recognizes annotations and takes care of them. If you really want to install MyServiceImpl from the @Configuration java class without calling the constructor yourself, you have to use a bean factory (did not check it, just try):

 @Configuration public class MyConfiguration { @Autowired AutowireCapableBeanFactory beanFactory; @Bean public MyService myService() { return beanFactory.createBean(MyServiceImpl.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true); } } 
+7
source

All Articles