Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting different beans depending on provided environment property

So I have an application that can be started for several different countries for example: mvn clean package -Dcountry=FRANCE resp. mvn clean package -Dcountry=GERMANY

For different countries I have different behavior especially when I'm validating stuff.

So I have this class that contains a country dependent validator:

@Component
public class SomeValidatingClass {

    private final Validator myCountrySpecificValidator;

    @Autowired
    public SomeValidatingClass(MyCountrySpecificValidator myCountrySpecificValidator) {
        this.myCountrySpecificValidator = myCountrySpecificValidator;
    }

    public void doValidate(Object target, Errors errors) {
        myCountrySpecificValidator.validate(target, errors);
    }
}

The first country dependent validator:

public class MyCountrySpecificValidator1 implements Validator {
    @Override
    public void validate(Object target, Errors errors) {
        if (target == null) {
            errors.rejectValue("field", "some error code");
        }
    }
}

The second country dependent validator: Let's assume for

public class MyCountrySpecificValidator2 implements Validator {
   @Override
   public void validate(Object target, Errors errors) {
       if (target != null) {
           errors.rejectValue("field", "some other error code");
       }
   }
}

My question is

  • how do I manage to inject an instance of MyCountrySpecificValidator1 into SomeValidatingClass when the application was startet with "-Dcountry=FRANCE"

and resp.

  • how do I manage to inject an instance of MyCountrySpecificValidator2 into SomeValidatingClass when the application was startet with "-Dcountry=GERMANY"
like image 324
IwantToKnow Avatar asked May 24 '17 11:05

IwantToKnow


1 Answers

You can use either @Conditional annotation to provide implementation depending on conditions. Like this

  @Bean(name="emailerService")
  @Conditional(WindowsCondition.class)
  public EmailService windowsEmailerService(){
      return new WindowsEmailService();
  }

  @Bean(name="emailerService")
  @Conditional(LinuxCondition.class)
  public EmailService linuxEmailerService(){
    return new LinuxEmailService();
  }

where e.g.

public class LinuxCondition implements Condition{

  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    return context.getEnvironment().getProperty("os.name").contains("Linux");  }
}

and you can use any property you need

or

use @Profile annotation defining active profile if you need multiple beans

read here

UPDATE:

Even simpler

@ConditionalOnProperty(name = "country", havingValue = "GERMANY", matchIfMissing = true) and annotate a method which return the germany validator. And the same for France.
like image 150
StanislavL Avatar answered Sep 27 '22 16:09

StanislavL