I have a Spring boot application that requires the use of properties in files different from the standard application.properties. I wanted to map my properties files to a specific properties class and be able to use the properties class inside of a Configuration class. The code is the following:
@Configuration @EnableConfigurationProperties(AWSProperties.class) @PropertySource("kaizen-batch-common-aws.properties") public class ResourceConfigAWS { @Autowired private AWSProperties awsProperties; @Autowired private ResourceLoader resourceLoader; private static final Logger logger = LoggerFactory.getLogger(ResourceConfigAWS.class); @Bean public AmazonS3 amazonS3Client() { logger.debug("AWS Config: " + this.awsProperties); BasicAWSCredentials awsCreds = new BasicAWSCredentials("access_key_id", "secret_key_id"); AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(awsCreds)) .withRegion(awsProperties.getRegion()) .build(); return s3Client; } @Bean public SimpleStorageResourceLoader resourceLoader() { return new SimpleStorageResourceLoader(this.amazonS3Client()); } @Bean @StepScope public Resource getResourceToProcess(@Value("#{jobParameters[T(com.kaizen.batch.common.JobRunnerTemplate).INPUT_FILE_PARAM_NAME]}") String inputFile) { return this.resourceLoader.getResource(this.awsProperties.getInputLocation() + inputFile); } @PostConstruct public void postConstruct() { System.out.print("Properties values: " + this.awsProperties); } @Bean public AbstractFileValidator inputFileValidator() { InputS3Validator inputS3Validator = new InputS3Validator(); inputS3Validator.setRequiredKeys(new String[]{InputFileSystemValidator.INPUT_FILE}); return inputS3Validator; } @Bean public InputFileFinalizerDelegate inputFileFinalizerDelegate() { InputFileFinalizerDelegate inputFileFinalizerDelegate = new AWSInputFileFinalizerDelegate(); return inputFileFinalizerDelegate; } @Bean public InputFileInitializerDelegate inputFileInitializerDelegate() { InputFileInitializerDelegate inputFileInitializerDelegate = new AWSInputFileInitializerDelegate(); return inputFileInitializerDelegate; } } @ConfigurationProperties("aws") @Data public class AWSProperties { private static final String SEPARATOR = "/"; private static final String S3_PREFFIX = "s3://"; @Value("${s3.bucket.batch}") private String bucket; @Value("${s3.bucket.batch.batch-job-folder}") private String rootFolder; @Value("${s3.bucket.batch.input}") private String inputFolder; @Value("${s3.bucket.batch.processed}") private String processedFolder; @Value("${region}") private String region; public String getInputLocation() { return this.getBasePath() + this.inputFolder + SEPARATOR; } public String getProcessedLocation() { return this.getBasePath() + this.processedFolder + SEPARATOR; } private String getBasePath() { return S3_PREFFIX + this.bucket + SEPARATOR + this.rootFolder + SEPARATOR; } } I am struggling to manage to Get AWSProperties to get populated with the values defined in the properties files, somehow I always end up with awsProperties with a null value. Any insight on how to map properties in Spring Boot into a Properties class without using the standard property files naming conventions in Spring Boot will be very appreciated.
Here is the properties file:
aws.s3.bucket.batch=com-kaizen-batch-dev aws.s3.bucket.batch.input=input aws.s3.bucket.batch.processed=processed aws.s3.bucket.batch.batch-job-folder=merchant-file aws.region=us-east-2 Note: I modified the Configuration class slightly and now I am getting the following exception:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.kaizen.batch.common.ResourceConfigAWS': Unsatisfied dependency expressed through field 'awsProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aws-com.kaizen.batch.common.AWSProperties': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 's3.bucket.batch' in value "${s3.bucket.batch}" at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
@ConfigurationProperties("aws")and the same time all configurable fields are annotated with@Value. Can you clarify which fields you are trying to configure using@ConfigurationProperties? Also include properties (key-value pairs) that you are going to bind with AWSProperties class.