On a project I'm currently working on, we have the need for multiple profiles, ie "default" and "cloud".
both DefaultContext and CloudContext contains the same bean definitions We are using PCF(Pivotal Cloud Foundry)
we have created an interface
public interface Config {
public DataSource getDataSource();
public SomeService getService();
}
Then implement each profile with this interface
@Primary
@Configuration
@Profile("default")
public class DevConfig implements Config
{
public DataSource getDataSource() {
// create and return production datasource
}
public SomeService getService() {
// Create and return production service
}
}
And then do the same for cloud.
@Configuratio
@Profile("cloud")
public class CloudConfig extends AbstractCloudConfig implements Config
{
public DataSource getDataSource() {
// create and return dummy datasource
}
public SomeService getService() {
// Create and return dummy service
}
}
And we are Autowiring in the service call, in processor file.
@Service("processor")
public class Processor {
@Autowired Config dsConfig;
public object get(int Number)
{
return dao.get(Number,dsConfig.getDataSource());
}
}
If we deploy in PCF, its working fine, as the profile is cloud. If we are running in local, it should get the default profile, but dsConfig is null. Could you please help on this.
@Configuration
classes aren't availalbe for autowiring.
As @spencergibb pointed out in the comment you need to tell the container to make this classes available for autowiring.
For that annotate them with @Component
.
Something like this:
@Component
@Profile("default")
public class DevConfig implements Config
{
public DataSource getDataSource() {
// create and return production datasource
}
public SomeService getService() {
// Create and return production service
}
}
In case it still doesn't work, check the following two points:
DevConfig
and Cloudconfig
) in different packages so the ContextScan doesn't find it? Dev
). You can put this snipped to your code (its from JHipster) to log the active profiles.
@Autowired
private Environment env;
/**
* Initializes Application.
* <p/>
* Spring profiles can be configured with a program arguments --spring.profiles.active=your-active-profile
* <p/>
*/
@PostConstruct
public void initApplication() throws IOException {
if (env.getActiveProfiles().length == 0) {
log.warn("No Spring profile configured, running with default configuration");
}
else {
log.info("Running with Spring profile(s) : {}", Arrays.toString(env.getActiveProfiles()));
}
}
I'd rather autowire datasource and service classes instead of configuration class. In this way you wouldn't need any instance of configuration and directly autowire whatever class you want.
So the classes will look like below. Default Config:
@Primary
@Configuration
@Profile("default")
public class DevConfig implements Config
{
@Bean
public DataSource getDataSource() {
// create and return production datasource
}
@Bean
public SomeService getService() {
// Create and return production service
}
}
Cloud Config:
@Configuration
@Profile("cloud")
public class CloudConfig extends AbstractCloudConfig implements Config
{
@Bean
public DataSource getDataSource() {
// create and return dummy datasource
}
@Bean
public SomeService getService() {
// Create and return dummy service
}
}
Processor Class:
@Service("processor")
public class Processor {
@Autowired
private DataSource dataSource;
public object get(int Number)
{
return dao.get(Number,datasource);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.