From 05f652e4bf69806c7dc25c77ded75f055712a3ff Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sun, 3 Mar 2024 15:20:06 +0530 Subject: [PATCH 1/5] BAEL-7521 - dynamically registering spring beans --- spring-di-4/src/main/resources/application.yml | 10 +++++++++- spring-di-4/src/test/resources/application.yml | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/spring-di-4/src/main/resources/application.yml b/spring-di-4/src/main/resources/application.yml index 5c09fdb8b0..51d20e5b40 100644 --- a/spring-di-4/src/main/resources/application.yml +++ b/spring-di-4/src/main/resources/application.yml @@ -1 +1,9 @@ -ambiguous-bean: 'A' \ No newline at end of file +ambiguous-bean: 'A' +api: + clients: + - name: example + url: https://api.example.com + key: 12345 + - name: anotherexample + url: https://api.anotherexample.com + key: 67890 \ No newline at end of file diff --git a/spring-di-4/src/test/resources/application.yml b/spring-di-4/src/test/resources/application.yml index da23e59c24..09ec2c0921 100644 --- a/spring-di-4/src/test/resources/application.yml +++ b/spring-di-4/src/test/resources/application.yml @@ -1 +1,9 @@ -ambiguous-bean: 'B' \ No newline at end of file +ambiguous-bean: 'B' +api: + clients: + - name: example + url: https://api.example.com + apiKey: 12345 + - name: anotherexample + url: https://api.anotherexample.com + apiKey: 67890 \ No newline at end of file From 4581d73fcedfe83b76a927cc032908cc05709b3c Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sun, 3 Mar 2024 15:20:33 +0530 Subject: [PATCH 2/5] BAEL-7521 - dynamically registering spring beans --- .../ApiClientConfiguration.java | 42 +++++++++++++++++ .../RegistryPostProcessorApplication.java | 22 +++++++++ .../registrypostprocessor/bean/ApiClient.java | 45 +++++++++++++++++++ .../ApiClientConfigurationTest.java | 23 ++++++++++ 4 files changed, 132 insertions(+) create mode 100644 spring-di-4/src/main/java/com/baeldung/registrypostprocessor/ApiClientConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/registrypostprocessor/RegistryPostProcessorApplication.java create mode 100644 spring-di-4/src/main/java/com/baeldung/registrypostprocessor/bean/ApiClient.java create mode 100644 spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationTest.java diff --git a/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/ApiClientConfiguration.java b/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/ApiClientConfiguration.java new file mode 100644 index 0000000000..db9d7f42f4 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/ApiClientConfiguration.java @@ -0,0 +1,42 @@ +package com.baeldung.registrypostprocessor; + +import com.baeldung.registrypostprocessor.bean.ApiClient; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; +import org.springframework.boot.context.properties.bind.Bindable; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.core.env.Environment; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ApiClientConfiguration implements BeanDefinitionRegistryPostProcessor { + private static final String API_CLIENT_BEAN_NAME = "apiClient_"; + List clients; + + public ApiClientConfiguration(Environment environment) { + Binder binder = Binder.get(environment); + List properties = binder.bind("api.clients", Bindable.listOf(HashMap.class)).get(); + clients = properties.stream().map(client -> new ApiClient(String.valueOf(client.get("name")), + String.valueOf(client.get("url")), String.valueOf(client.get("key")))).toList(); + } + + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + clients.forEach(client -> { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ApiClient.class); + builder.addPropertyValue("name", client.getName()); + builder.addPropertyValue("url", client.getUrl()); + builder.addPropertyValue("key", client.getKey()); + registry.registerBeanDefinition(API_CLIENT_BEAN_NAME + client.getName(), builder.getBeanDefinition()); + }); + } + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + } +} \ No newline at end of file diff --git a/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/RegistryPostProcessorApplication.java b/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/RegistryPostProcessorApplication.java new file mode 100644 index 0000000000..311f72e0fa --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/RegistryPostProcessorApplication.java @@ -0,0 +1,22 @@ +package com.baeldung.registrypostprocessor; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.ConfigurableEnvironment; + + +@SpringBootApplication +public class RegistryPostProcessorApplication { + + public static void main(String[] args) { + SpringApplication.run(RegistryPostProcessorApplication.class, args); + } + + @Bean + public ApiClientConfiguration apiClientConfiguration(ConfigurableEnvironment environment) { + return new ApiClientConfiguration(environment); + } + +} + diff --git a/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/bean/ApiClient.java b/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/bean/ApiClient.java new file mode 100644 index 0000000000..00d7f58a9a --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/bean/ApiClient.java @@ -0,0 +1,45 @@ +package com.baeldung.registrypostprocessor.bean; + +public class ApiClient { + private String name; + private String url; + private String key; + + public ApiClient(String name, String url, String key) { + this.name = name; + this.url = url; + this.key = key; + } + + public ApiClient() { + } + + public String getName() { + return name; + } + + public String getUrl() { + return url; + } + + public String getKey() { + return key; + } + + public String getConnectionProperties() { + return "Connecting to " + name + " at " + url; + } + + public void setName(String name) { + this.name = name; + } + + public void setUrl(String url) { + this.url = url; + } + + public void setKey(String key) { + this.key = key; + } + +} \ No newline at end of file diff --git a/spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationTest.java b/spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationTest.java new file mode 100644 index 0000000000..6e38152332 --- /dev/null +++ b/spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationTest.java @@ -0,0 +1,23 @@ +package com.baeldung.registrypostprocessor; + +import com.baeldung.registrypostprocessor.bean.ApiClient; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; + +@SpringBootTest(classes = RegistryPostProcessorApplication.class) +public class ApiClientConfigurationTest { + @Autowired + private ApplicationContext context; + + @Test + void givenBeansRegistered_whenConnect_thenConnected() { + ApiClient exampleClient = (ApiClient) context.getBean("apiClient_example"); + Assertions.assertEquals("Connecting to example at https://api.example.com", exampleClient.getConnectionProperties()); + + ApiClient anotherExampleClient = (ApiClient) context.getBean("apiClient_anotherexample"); + Assertions.assertEquals("Connecting to anotherexample at https://api.anotherexample.com", anotherExampleClient.getConnectionProperties()); + } +} \ No newline at end of file From bbd70d96038866bf141bc5adf3c61b54a8529a72 Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sun, 3 Mar 2024 15:33:36 +0530 Subject: [PATCH 3/5] BAEL-7521 - dynamically registering spring beans --- .../baeldung/registrypostprocessor/ApiClientConfiguration.java | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/ApiClientConfiguration.java b/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/ApiClientConfiguration.java index db9d7f42f4..5faf5d2707 100644 --- a/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/ApiClientConfiguration.java +++ b/spring-di-4/src/main/java/com/baeldung/registrypostprocessor/ApiClientConfiguration.java @@ -12,7 +12,6 @@ import org.springframework.core.env.Environment; import java.util.HashMap; import java.util.List; -import java.util.Map; public class ApiClientConfiguration implements BeanDefinitionRegistryPostProcessor { private static final String API_CLIENT_BEAN_NAME = "apiClient_"; From 619842cd596ed29d3af983b932c8ec2139e130d0 Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sun, 3 Mar 2024 15:38:04 +0530 Subject: [PATCH 4/5] BAEL-7521 - dynamically registering spring beans --- ...nfigurationTest.java => ApiClientConfigurationUnitTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename spring-di-4/src/test/java/com/baeldung/registrypostprocessor/{ApiClientConfigurationTest.java => ApiClientConfigurationUnitTest.java} (95%) diff --git a/spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationTest.java b/spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationUnitTest.java similarity index 95% rename from spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationTest.java rename to spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationUnitTest.java index 6e38152332..80e578166c 100644 --- a/spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationTest.java +++ b/spring-di-4/src/test/java/com/baeldung/registrypostprocessor/ApiClientConfigurationUnitTest.java @@ -8,7 +8,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; @SpringBootTest(classes = RegistryPostProcessorApplication.class) -public class ApiClientConfigurationTest { +public class ApiClientConfigurationUnitTest { @Autowired private ApplicationContext context; From 9d7262f27d4c95f32450feccebe4862eab5c5b31 Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sun, 3 Mar 2024 15:45:41 +0530 Subject: [PATCH 5/5] BAEL-7521 - adding main class in properties --- spring-di-4/pom.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/spring-di-4/pom.xml b/spring-di-4/pom.xml index 1eec8efcf0..a486b19e51 100644 --- a/spring-di-4/pom.xml +++ b/spring-di-4/pom.xml @@ -24,5 +24,15 @@ spring-boot-starter-test - + + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.registrypostprocessor.RegistryPostProcessorApplication + + + + \ No newline at end of file