javaspringjavabeansconditional-on-property

Parameter 0 of constructor when using @ConditionalOnProperty


I'm writing a send email service with AWS SES. I add a

@conditionalOnProperty 

on this service to control whether it works or not.

@Configuration
@RequiredArgsConstructor
public class MailConfig {
    private final SystemParam systemParam;
    @Bean
    @ConditionalOnProperty(name = "system-param.aws-active",havingValue = "true")
    public AmazonSimpleEmailService amazonSimpleEmailService() {
        String awsAccessKey = systemParam.getAWS_ACCESS_KEY();
        String awsSecretKey = systemParam.getAWS_SECRET_KEY();
        return AmazonSimpleEmailServiceClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(
                        new BasicAWSCredentials(
                               awsAccessKey,awsSecretKey)))
                .withRegion(Regions.AP_SOUTHEAST_2)
                .build();
    }

}

When I do not want to inject it, I will set the aws-active to false. But when running the application, the error will come out:

Description:

Parameter 0 of constructor in com.eta.houzezbackend.service.EmailService required a bean of type 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService' that could not be found.


Action:

Consider defining a bean of type 'com.amazonaws.services.simpleemail.AmazonSimpleEmailService' in your configuration.

I understand that is because my other classes which use the AmazonSimpleEmailService will need it to be injected:

public record EmailService(AmazonSimpleEmailService amazonSimpleEmailService, SystemParam systemParam) {
...
}

But how to I deal with this if I do not want it to be registered as bean?

Looking forward to your suggestions!


Solution

  • You have two options:

    However, the best way to use conditional beans is via inheritance: several concrete services implementing a common interface. Then you make the autowire optional, or you put your conditions so that there is always one loaded bean.

    Short example:

    public interface ProducerService {
      ...
    }
    
    @ConditionalOnProperty(name="xxx", value="true")
    public class Producer1Service implements ProducerService {
      ...
    }
    
    @ConditionalOnProperty(name="xxx", value="false")
    public class Producer2Service implements ProducerService {
      ...
    }
    
    public class ConsumerService {
      @Autowired private ProducerService producerService;
      ...
    }