{"id":3008,"date":"2025-12-24T10:00:26","date_gmt":"2025-12-24T15:00:26","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3008"},"modified":"2025-12-24T10:00:26","modified_gmt":"2025-12-24T15:00:26","slug":"spring-annotation-w-dynamic-service-loading","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/springboot\/spring-annotation-w-dynamic-service-loading\/","title":{"rendered":"Spring Annotation w\/Dynamic Service Loading"},"content":{"rendered":"\n<p>Recently a project I was working on required the ability to load up a number of unknown services that implemented a Calendar Provider Interface. As this was a <a href=\"http:\/\/spring.io\" data-type=\"URL\" data-id=\"http:\/\/spring.io\">Spring <\/a>server, I started looking around trying to find the right way to do this.  I began by looking at being able to add an annotation to a class to identify the class as a Calendar Service Provider.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import java.lang.annotation.ElementType;\r\nimport java.lang.annotation.Retention;\r\nimport java.lang.annotation.RetentionPolicy;\r\nimport java.lang.annotation.Target;\r\n\r\n@Retention(RetentionPolicy.RUNTIME)\r\n@Target(ElementType.TYPE)\r\npublic @interface CalendarServiceProvider {\r\n}<\/code><\/pre>\n\n\n\n<p>Nothing fancy about the annotation, just a flag on the class at runtime.  Next was a way to find the instances with the annotation. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ClassPathScanningCandidateComponentProvider provider\r\n                = new ClassPathScanningCandidateComponentProvider(false);\r\n        provider.addIncludeFilter(new AnnotationTypeFilter(CalendarServiceProvider.class));\r\n\r\n        Set&lt;BeanDefinition> providers = provider.findCandidateComponents(\"com.blue.project\");<\/code><\/pre>\n\n\n\n<p>Now this was much easier than I had thought it would be.  I scan com.blue.project for any classes with the annotation type of CalendarServiceProvider.class.  However this gives me a BeanDefinition for the class.  After a little trial and error  I came up with the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>providers.stream().map(BeanDefinition::getBeanClassName).map(name -> {\r\n            return name.substring(name.lastIndexOf('.')+1);\r\n        }).map(beanName -> {\r\n            return Character.toLowerCase(beanName.charAt(0)) + beanName.substring(1);\r\n        }).map(beanName -> {\r\n            return applicationContext.getBean(beanName);\r\n        }).map(bean -> {\r\n            if(bean instanceof CalendarServiceProviderInterface) {\r\n                return (CalendarServiceProviderInterface)bean;\r\n            }\r\n            return null;\r\n        }).filter(Objects::nonNull).collect(Collectors.toList());<\/code><\/pre>\n\n\n\n<p>Couple of things to point out I take the simple name of the class, then I convert the first character to lowercase, and this allows me to load an existing bean of that type.  Then for good measure I run it through another map to check verify it has the Interface I want implemented on the bean, if it does I pass it along, else I return a null.  Then a final filter to remove the nulls, and then collect everything else to a list.<\/p>\n\n\n\n<p>My completed method looks like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@Autowired\r\n    private ApplicationContext applicationContext;\n\nprivate List&lt;CalendarServiceProviderInterface> findCalendarServiceProviders() {\r\n        ClassPathScanningCandidateComponentProvider provider\r\n                = new ClassPathScanningCandidateComponentProvider(false);\r\n        provider.addIncludeFilter(new AnnotationTypeFilter(CalendarServiceProvider.class));\r\n\r\n        Set&lt;BeanDefinition> providers = provider.findCandidateComponents(\"com.blue.project\");\r\n\r\n        return providers.stream().map(BeanDefinition::getBeanClassName).map(name -> {\r\n            return name.substring(name.lastIndexOf('.')+1);\r\n        }).map(beanName -> {\r\n            return Character.toLowerCase(beanName.charAt(0)) + beanName.substring(1);\r\n        }).map(beanName -> {\r\n            return applicationContext.getBean(beanName);\r\n        }).map(bean -> {\r\n            if(bean instanceof CalendarServiceProviderInterface) {\r\n                return (CalendarServiceProviderInterface)bean;\r\n            }\r\n            return null;\r\n        }).filter(Objects::nonNull).collect(Collectors.toList());\r\n    }<\/code><\/pre>\n\n\n\n<p>You will need to autowire in the ApplicationContext.  Simple enough of a process to implement.  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently a project I was working on required the ability to load up a number of unknown services that implemented a Calendar Provider Interface. As this was a Spring server, I started looking around trying to find the right way to do this. I began by looking at being able to add an annotation to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3009,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Spring Annotation w\/Dynamic Service Loading","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[448],"tags":[319],"series":[397],"class_list":["post-3008","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-springboot","tag-spring","series-spring"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2021\/03\/computer-1343393_640.jpg?fit=640%2C360&ssl=1","jetpack-related-posts":[{"id":3795,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/evrete-a-modern-java-rule-engine\/","url_meta":{"origin":3008,"position":0},"title":"EVRete: A Modern Java Rule Engine","author":"Jeffery Miller","date":"November 24, 2025","format":false,"excerpt":"EVRete is a high-performance, lightweight, and open-source rule engine designed for Java applications. It offers a flexible and expressive way to implement rule-based logic, making it a compelling alternative to traditional rule engines like Drools. This article delves into EVRete\u2019s features, focusing on its annotation-based approach to rule definition. Why\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/compliance-5899194_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/compliance-5899194_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/compliance-5899194_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/compliance-5899194_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/compliance-5899194_1280-jpg.avif 3x"},"classes":[]},{"id":3909,"url":"https:\/\/www.mymiller.name\/wordpress\/spring\/making-injected-parameters-optional-in-spring-boot\/","url_meta":{"origin":3008,"position":1},"title":"Making Injected Parameters Optional in Spring Boot","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"As a software architect building solutions with Spring Boot, you'll often encounter scenarios where a component or service needs to consume another dependency that may not always be available. This could be due to a feature toggle, an environment-specific configuration, or a third-party integration that is only present in certain\u2026","rel":"","context":"In &quot;Spring&quot;","block_context":{"text":"Spring","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/option-1010899_1280.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/option-1010899_1280.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/option-1010899_1280.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/option-1010899_1280.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/09\/option-1010899_1280.avif 3x"},"classes":[]},{"id":3466,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_shell\/exploring-spring-shell-a-comprehensive-guide\/","url_meta":{"origin":3008,"position":2},"title":"Exploring Spring Shell: A Comprehensive Guide","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Spring Shell seamlessly integrates command-line applications with the Spring framework, offering a robust and flexible environment for developers. In this article, we'll expand on setting up a Spring Shell project and explore its features, with a detailed focus on parameters, options, and annotations available for crafting powerful commands in Java.\u2026","rel":"","context":"In &quot;Spring Shell&quot;","block_context":{"text":"Spring Shell","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_shell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/06\/coding-699318_640.jpg?fit=640%2C437&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/06\/coding-699318_640.jpg?fit=640%2C437&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/06\/coding-699318_640.jpg?fit=640%2C437&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3846,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_databases\/speed-and-reliability-unit-testing-with-mongodb-memory-server-in-spring-boot\/","url_meta":{"origin":3008,"position":3},"title":"Speed and Reliability: Unit Testing with MongoDB Memory Server in Spring Boot","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"When you\u2019re building Spring Boot applications that interact with MongoDB, ensuring the reliability of your data access layer is crucial. Unit tests play a vital role, but setting up and tearing down a real MongoDB instance for each test can be slow and cumbersome. This is where MongoDB Memory Server\u2026","rel":"","context":"In &quot;Spring Databases&quot;","block_context":{"text":"Spring Databases","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_databases\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/scientist-9234951_1280-png.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/scientist-9234951_1280-png.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/scientist-9234951_1280-png.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/scientist-9234951_1280-png.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/04\/scientist-9234951_1280-png.avif 3x"},"classes":[]},{"id":3380,"url":"https:\/\/www.mymiller.name\/wordpress\/java\/synchronous-to-asynchronous\/","url_meta":{"origin":3008,"position":4},"title":"Synchronous to Asynchronous","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Converting a synchronous method to an asynchronous one in Java involves modifying the code to allow other tasks to execute while it is waiting for input\/output operations to complete. Here's an example of how to convert a synchronous method to an asynchronous one in Java: Let's say we have a\u2026","rel":"","context":"In &quot;JAVA&quot;","block_context":{"text":"JAVA","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/06\/multitasking-ga6749a2b2_640.jpg?fit=640%2C394&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/06\/multitasking-ga6749a2b2_640.jpg?fit=640%2C394&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/06\/multitasking-ga6749a2b2_640.jpg?fit=640%2C394&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3786,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/integrating-easy-rules-with-a-spring-boot-microservice\/","url_meta":{"origin":3008,"position":5},"title":"Integrating Easy Rules with a Spring Boot Microservice","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"This post will walk you through integrating the lightweight and straightforward Easy Rules engine with your Spring Boot microservice. We'll cover the necessary dependencies, basic setup, and an example service to demonstrate its usage. 1. Project Setup and Dependencies Start by creating a Spring Boot project. Next, add the following\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/10\/office-4249395_1280-jpg.avif 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3008","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=3008"}],"version-history":[{"count":2,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3008\/revisions"}],"predecessor-version":[{"id":3011,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3008\/revisions\/3011"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3009"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3008"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3008"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3008"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3008"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}