I would like to create a builder class (i.e. a class implementing the builder design pattern) in a Spring project.
The problem is that I need the builder to use some Spring services.
I obviously don't want the user to explicitly provide the services in the constructor, but when I tried to @Autowire
the services, I got Autowired members must be defined in valid Spring bean
. I could Annotate my builder with @Component
, but that would make it a singleton which will not be desirable for a builder.
How can I inject services to my builder class without making it a singleton?
To use the example from this article, lets say I have the following builder:
BankAccount account = new BankAccount.Builder(1234L)
.withOwner(25324)
.atBranch("Springfield")
.openingBalance(100)
.atRate(2.5)
.build();
I want withOwner
to use my UserService
to get the actual user from the database given the id number received as a parameter. How would I go about injecting UserService to builder?
How would I go about injecting UserService to builder?
In your spring bean definitions, you cannot and have not to mix objects managed by Spring and these created by yourself and which Spring is not aware.
While you may make it working but it should be used only in very specific rare cases and generally for legacy/third party dependencies reasons, not in a code where you can change that.
Definitively, you want to inject beans dependencies in beans.
This runtime error message means that you don't respect this rule :
but when I tried to @Autowire the services, I got Autowired members must be defined in valid Spring bean
About :
I could Annotate my builder with @Component, but that would make it a singleton which will not be desirable for a builder.
singleton
is the default scope but Spring allows you to specify other scopes for a component. Just define it as a prototype
bean and it will create a new instance of it at each call.
public class BankAccount{
// ...
@Component
@Scope(value="prototype")
public static class Builder{
//...
}
}