3

On a project I'm currently working on, we have the need for multiple profiles, i.e. "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.

d0x
  • 11,040
  • 17
  • 69
  • 104
Vamsinag R
  • 51
  • 4

2 Answers2

2

@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:

  • Do you have the configs (DevConfig and Cloudconfig) in different packages so the ContextScan doesn't find it?
  • Are you running in another profile locally? (like 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()));
        }
    }
d0x
  • 11,040
  • 17
  • 69
  • 104
  • Thank you. I checked the points that you mentioned. 1. both DevConfig and CloudConfig are in same packages. 2. I am running in default profile in local. When I checked the logs with the code. I got the below message "No Spring profile configured, running with default configuration". But the dsConfig is null – Vamsinag R Dec 15 '15 at 18:10
0

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);
    }
}
kosker
  • 333
  • 1
  • 3
  • 12