Reputation: 83
I have a component EmbeddedRedis
that depends on a configuration object RedisConfig
parsed from the application's property file. There are different property files, corresponding to the possible application profiles that can be run. Thus, when run in profile master
, the component EmbeddedRedis
will be provisioned according to the master
profile.
In a test class, that is supposed to set-up a local Redis cluster, I also require Redis
objects provisioned according to all other profiles. I sketched my idea below using the @Qualifier
annotation, which does not bring the desired result.
@Autowired @Qualifier("dev-cluster-master")
private Redis embeddedRedisMaster;
@Autowired @Qualifier("dev-cluster-slave-001")
private Redis embeddedRedisSlave1;
@Autowired @Qualifier("dev-cluster-slave-002")
private Redis embeddedRedisSlave2;
How can I archive the desired result in Spring Boot? If that doesn't work directly, would it also suffice to obtain the before-mentioned configuration objects parsed from the different property files.
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisConfig {
....
}
Thanks in advance!
Upvotes: 1
Views: 9086
Reputation: 1545
If you need your component only with certain profile and you don't want to or can't create a common interface you could inject like this:
@Autowired
private Optional< Redis > redis;
You would have to check if present on each different object on every profile.
If you share a common interface use the other answer solution to create different beans implementing the interface per each profile.
Upvotes: 1
Reputation: 71
You can do something like this: Consider you have an interface definition:
public interface SomeService {
String someMethod;
}
And two implemented class:
@Profile("production")
@Service
public class SomeServiceProd implements SomeService {
@Override String someMethod() {return "production";}
}
@Profile("development")
@Service
public class SomeServiceProd implements SomeService {
@Override String someMethod() {return "development";}
}
And use this service in test and main code:
@Autowired SomeService service;
Upvotes: 2
Reputation: 6932
You can do something like this: Consider you have a class definition (Redis in your example)
public class CustomService {
private String name;
public CustomService(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And a configuration class like:
@Configuration
public class Config {
@Bean
@Profile("master")
CustomService serverConfig1(){
CustomService service1 = new CustomService("master");
return service1;
}
@Bean
@Profile("slave")
CustomService serverConfig2(){
CustomService service1 = new CustomService("slave");
return service1;
}
}
which initiate 2 different objects based on current active profile. If current active profile is "master", then serverConfig1() will get executed, otherwise serverConfig2().
And finally autowired your service/object like this:
@Autowired
CustomService service;
This will depends on above executed bean definition in configuration file.
And property file should look like this:
spring.profiles.active=slave
So in this example, after executing above code, the value of 'name' in CustomService service;
will be "slave" instead of "master", because current active profile is "slave" and thus "serverConfig2()" will get executed
Upvotes: 3