Issue Details (XML | Word | Printable)

Key: SJC-50
Type: New Feature New Feature
Status: Resolved Resolved
Resolution: Deferred
Priority: Major Major
Assignee: Chris Beams
Reporter: Chris Beams
Votes: 1
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Spring JavaConfig

Support autowired parameters to @Bean creation methods

Created: 14/Dec/07 08:38 AM   Updated: 05/Sep/08 08:37 PM   Resolved: 05/Sep/08 08:37 PM
Component/s: None
Affects Version/s: None
Fix Version/s: None

Time Tracking:
Not Specified

Issue Links:
Depends
 
Related
 


 Description  « Hide
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);
        }
    }



Chris Beams added a comment - 14/Dec/07 08:45 AM
Resolving SJC-50 (autowired parameters to @Bean creation methods). This was a very simple, two line change. If bean creation methods have parameters, Confi
gurationProcessor 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

Chris Beams added a comment - 15/Dec/07 08:43 AM
Backing out changes for SJC-50 for now. This is not a complete replacement for @ExternalBean as intended, so no need to rush it in. We'll reconsider this post-M3.
--This line, and those below, will be ignored--

D trunk/src/test/java/org/springframework/config/java/ParameterizedBeanMethodTests.java
M trunk/src/main/java/org/springframework/config/java/process/ConfigurationProcessor.java

Sending trunk/src/main/java/org/springframework/config/java/process/ConfigurationProcessor.java
Deleting trunk/src/test/java/org/springframework/config/java/ParameterizedBeanMethodTests.java
Transmitting file data .
Committed revision 9446.

Baruch Sadogursky added a comment - 29/May/08 06:06 AM
How about using @Autowired for that matter? After all, Configuration is a bean, and the dependency needed is also a bean. Spring already has a generic way of injecting beans into other beans, why not reusing it?

Jim Moore added a comment - 29/May/08 06:16 AM
Baruch, can you give an example of code that would use the @Autowired annotation? I'm not sure how that would resolve the issue, so I'm hoping see the code you're thinking of will help. You may want to also take a look at SJC-62

Chris Beams added a comment - 05/Sep/08 08:37 PM
@Bean method parameters are not currently supported and may never be. If so, this issue will become relevant again. Until then, resolving as deferred.