Background: Let's say I'm in the process of migrating code from old code to Spring Boot 2 applications. The old code had its own IoC mechanism and I'd like to reuse old libraries in new Spring app without modifying the libraries codebase.
Libraries code used field-injections only. It used annotation similar to @Value
for injecting some properties, let's say @InjectString
. Also every field also had @Inject
annotation on top. So all libraries that I'd like to use look more or less like this:
package com.mylibrary;
public class LibraryA {
@Inject
@InjectString("db.properties.poolEnabled")
private String poolEnabled;
...
Assumption:
- all properties like
db.properties.poolEnabled
are already present inSystem.getProperties()
. - the
LibraryA
class is already under Spring IoC control, it's just missing the required field bean:
No qualifying bean of type 'java.lang.String' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject(), @com.mylibrary.InjectString(name="db.properties.poolEnabled")}
Question:
How can I reuse old code and let Spring know what values to put dynamically into the fields with @Inject
based on @InjectString
name (which can be retrieved from System.getProperty
?
I was thinking about 3 potential solutions:
during beans construction, let Spring know that when it's looking for a Bean of type String and it the field has
@InjectString
annotation, it can get a value fromSystem.getProperty()
as the bean value.during class scan, take all fields with
@InjectString
and somehow append there a@Value
annotations and maybe Spring will know what to insert therescan for all fields annotated with
@InjectString
, create String named beans for all of them and append@Resource(name="...")
to every fields bean declaration
Which idea sounds the best and which Spring classes will help with implementation?
So far I'd probably prefer solution 1), as it sounds like a single Spring class override. In solution 2) and 3) I'm missing the Spring classes I can override during IoC building to provide extra beans definitions dynamically - do you know what can I use?
Thanks for any hints!
Looking at
@Value
javadoc we will see hint, that processing is done inAutowiredAnnotationBeanPostProcessor
and binding is done inAutowireCandidateResolver
.So, I would try with registering additional
BeanPostProcessor
that will have you@InjectString
set asautowiredAnnotationTypes
. Then registerQualifierAnnotationAutowireCandidateResolver
with this annotation.