Reputation: 29518
Most of my classes wired up look something like:
@Component
public class MyClassImpl implements MyClass {
private MyService service;
@Autowired
public MyClass(MyService service) {
this.service = service;
}
}
So that makes sense to me, but if I want to do something like this:
@Component
public class MyClassImpl implements MyClass {
private MyService service;
private String id; // this is what I need
@Autowired
public MyClass(MyService service, String id) {
this.service = service;
this.id = id;
}
}
But the problem is String id
is not known until runtime. Is there any way to do this? From what I can tell, Spring checks all the dependencies by default at runtime so if I try the second example, it complains about the constructor arguments.
I've seen some examples where you can use a factory to create the actual value later down the line. Or I can create getters and setters in order to set the id
when I need it, but that would also mean I'd need to add those getters and setters to the interface MyClass
as well. Is there a cleaner way to do this?
Upvotes: 1
Views: 1531
Reputation: 10425
You can create a @Bean method for id with logic needed to calculate it.
@Configuration
public class Config {
@Bean
public String idForService() {
return calculateId();
}
}
And then your service constructor will be look like this
@Autowired
public MyClass(MyService service, @Qualifier("idForService") String id) {
this.service = service;
this.id = id;
}
But as others have already mentioned it looks like a bad practice so you'd better consider to redesign your service class.
Upvotes: 1
Reputation: 1280
I am afraid what you are trying to do is not in the spirit of what Spring was created for. Please do have a look at: Runtime dependency injection with Spring
Having said that, there might be a workaround to your problem. If you have some class that calculates that ID for you, just inject that class in a constructor and bind the result of its calculation to the field id in your class.
Upvotes: 0