
| Key: |
SJC-50
|
| Type: |
New Feature
|
| Status: |
Resolved
|
| Resolution: |
Deferred
|
| Priority: |
Major
|
| Assignee: |
Chris Beams
|
| Reporter: |
Chris Beams
|
| Votes: |
1
|
| Watchers: |
1
|
|
If you were logged in you would be able to see more operations.
|
|
|
|
Issue Links:
|
Depends
|
|
|
|
This issue is depended on by:
|
|
SJC-51
Support use of @Qualifier for autowired parameters to @Bean creation methods
|
|
|
|
|
Related
|
|
|
|
This issue is related to:
|
|
SJC-62
Allow @AutoBean to wire constructor arguments
|
|
|
|
|
SJC-74
Support @Bean method parameter annotations for PropertyPlaceholderConfigurer-style injection
|
|
|
|
|
|
|
|
Currently there are two approaches to resolving dependencies between modularized JavaConfig @Configuration classes. Both work, but have significant downsides:
1) @ExternalBean
@Configuration
public abstract class AppConfig {
@Bean
public OrderService orderService() {
return new OrderServiceImpl(orderRepository());
}
}
@ExternalBean
public abstract OrderRepository orderRepository();
The 'external bean' will need to be provided by some other contributor to the ApplicationContext at runtime. Could be another JavaConfig @Configuration class, could be definitions out of XML, etc.
Downsides here are that the syntax is a little awkward and 'clever'. User is encouraged to use abstract, but it's not immediately clear why, or what happens with that abstract method (user would have to think about CGLIB-based implementation to truly understand it, etc)
2) extend ConfigurationSupport and lookup beans with getBean()
@Configuration
public abstract class AppConfig extends ConfigurationSupport {
@Bean
public OrderService orderService() {
return new OrderServiceImpl((OrderRepository) this.getBean("orderRepository");
}
}
again, our 'orderRepository' bean will be provided by some other contributor of bean definitions at runtime.
Downsides to this approach include having to subclass ConfigurationSupport, and fragile string-based lookups (can be a little bit better if using the new type-safe getBean() method on ConfigurationSupport, but is still somewhat cumbersome, feels like dependency lookup rather than dependency injection.
The solution:
A more elegant approach to modularizing configurations would be to supply dependencies as parameters to bean creation methods. Applying this to our example above, syntax becomes very intuitive / familiar:
@Configuration
public abstract class AppConfig extends ConfigurationSupport {
@Bean
public OrderService orderService(OrderRepository orderRepository) {
return new OrderServiceImpl(orderRepository);
}
}
|
|
Description
|
Currently there are two approaches to resolving dependencies between modularized JavaConfig @Configuration classes. Both work, but have significant downsides:
1) @ExternalBean
@Configuration
public abstract class AppConfig {
@Bean
public OrderService orderService() {
return new OrderServiceImpl(orderRepository());
}
}
@ExternalBean
public abstract OrderRepository orderRepository();
The 'external bean' will need to be provided by some other contributor to the ApplicationContext at runtime. Could be another JavaConfig @Configuration class, could be definitions out of XML, etc.
Downsides here are that the syntax is a little awkward and 'clever'. User is encouraged to use abstract, but it's not immediately clear why, or what happens with that abstract method (user would have to think about CGLIB-based implementation to truly understand it, etc)
2) extend ConfigurationSupport and lookup beans with getBean()
@Configuration
public abstract class AppConfig extends ConfigurationSupport {
@Bean
public OrderService orderService() {
return new OrderServiceImpl((OrderRepository) this.getBean("orderRepository");
}
}
again, our 'orderRepository' bean will be provided by some other contributor of bean definitions at runtime.
Downsides to this approach include having to subclass ConfigurationSupport, and fragile string-based lookups (can be a little bit better if using the new type-safe getBean() method on ConfigurationSupport, but is still somewhat cumbersome, feels like dependency lookup rather than dependency injection.
The solution:
A more elegant approach to modularizing configurations would be to supply dependencies as parameters to bean creation methods. Applying this to our example above, syntax becomes very intuitive / familiar:
@Configuration
public abstract class AppConfig extends ConfigurationSupport {
@Bean
public OrderService orderService(OrderRepository orderRepository) {
return new OrderServiceImpl(orderRepository);
}
}
|
Show » |
Sort Order:
|
SJC-50(autowired parameters to @Bean creation methods). This was a very simple, two line change. If bean creation methods have parameters, ConfigurationProcessor ensures that the resulting BeanDefinition is set to autowireMode == AUTOWIRE_CONSTRUCTOR. Remember that the 'constructor arguments' that are being autowired are actually factory method arguments.
--This line, and those below, will be ignored--
AM src/test/java/org/springframework/config/java/ParameterizedBeanMethodTests.java
M src/main/java/org/springframework/config/java/process/ConfigurationProcessor.java