Skip to content

Java based config should support class-only component declarations through @Import [SPR-11740] #16362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Apr 26, 2014 · 8 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Apr 26, 2014

Marty Pitt opened SPR-11740 and commented

Currently, when declaring my beans via Java config, I'm provided with two options:

  • Implicitly, without construction responsibility -- Using a @Component annotation, and let Spring discover the bean.
  • Explicitly, with construction responsibility -- Using a @Bean annotation within a @Configuration class.

There is a valid use case where I would like to explicitly declare a set of beans, but leave Spring responsible for their construction.

This is analogous to the classic <bean class=""> xml approach.

A possible syntax for this would be:

@Configuration 
public class MyAppConfig {

    // Explictly provide the class, not the instance to Spring
    @Bean
    public MyFunkySpringBean funkyBean; // No instance -- it's up to Spring to build
}

Reference URL: http://stackoverflow.com/questions/23313262/spring-java-config-specify-class-only

Issue Links:

Referenced from: commits f0ac278, a15dc08

1 votes, 9 watchers

@spring-projects-issues
Copy link
Collaborator Author

Luiggi Mendoza commented

This would be hard to accomplish. What would happen if instead <pre>MyFunkySpringBean</pre> you have <pre>Long</pre> or <pre>String</pre> classes or an immutable class that requires specific arguments?

@spring-projects-issues
Copy link
Collaborator Author

Marty Pitt commented

I don't see how rejecting that as invalid is any harder than rejecting the analogous XML as invalid:

<bean class ='Java.lang.long" I'd="invalid" />

Ultimately, I'd expect these two syntaxes are the same.

Sent from my phone.... Apologies for any typos.

@spring-projects-issues
Copy link
Collaborator Author

cemo koc commented

In that case:

@Bean
public MyFunkySpringBean funkyBean = new MyFunkySpringBean(1l, "");

@spring-projects-issues
Copy link
Collaborator Author

Marty Pitt commented

Would expect that if a @Bean annotated method / field that provides a value, that it would behave as it currently does. (I.e., a value is returned).

This has different semantics than a declared annotated field which provides no value, only a type.

Ultimately, the syntax itself I'm not too fussed on... Only a means of saying to the spring container: "Hey... I want one of these, and I want you to build it, best as you can". This is what the XML equivalent says.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 26, 2014

Juergen Hoeller commented

We have a related feature issue: #15547... It originated in a discussion about support for @Bean on Java 8 default methods and then moved on to a consideration of abstract @Bean methods on interfaces, similar to the discussion here. This turns out to be rather non-trivial to implement within Spring's configuration class processing algorithm, next to all the existing options there, but it certainly sounds attractive from a usage perspective.

Our plate for Spring Framework 4.1 is pretty full at this point, with an RC1 planned in June and a GA target in July, so I can't make any promises about this idea being considered for it still. However, it's certainly a key feature candidate for Spring Framework 4.2, scheduled for Q1 2015.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

AnnotationConfigApplicationContext's register method effectively operates like that as well: taking the given Class references and registering them as component classes (or configuration classes) with the container, just like if they were found through component scanning. That said, this isn't easily reachable from within an @Configuration class... I guess the closest we have there is @Import but that's not really meant to be used with non-configuration classes as target.

A dedicated @Bean signature would allow for declaring explicit metadata at that level, not having to embed such metadata into the component class itself. Except for that specific benefit, an @Import approach that just enumerates annotated component classes would do the job as well, wouldn't it...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

I've relaxed our @Import rules to allow for enumerating regular component classes as well, analogous to AnnotationConfigApplicationContext.register. This is also a pretty direct equivalent to <bean class="...">. Note that bean metadata (qualifiers etc) needs to be put onto the component class itself in that case since there's no other place to put it.

This is a very straightforward change and from my perspective at the right side of the 80/20 tradeoff. Given the ease of allowing for this, I am not in favor of adding field-based declarations for the same purpose. Abstract methods would have the additional benefit of allowing for cross-method calls like with regular @Bean methods; however, since that specific benefit would come at rather high complexity, I'm opting out of that as well.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Steven Schlansker commented

It would be nice if this feature was documented, I had to find this from a link on Stack Overflow and it's a pretty nice feature!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants