I have a class which is created with new B(this);
in this class B I want to use a value from the application.properties. But because (as far as I understand) because it’s not created with Spring it won’t have any injection (I use the @Value
annotation)
That is how the class is created:
@Component public class A { public B getB(){return new B(this);} /** a lot more stuff **/ }
The class in question:
public class B { private A a; public B(A a){ this.a = a; } @Value("${threshold}") private String threshold; //this is null because it's not created with Spring public String getThreshold(){ return threshold; } /** a lot more stuff **/ }
So my question is the following:
1) How can I use the value in the application.properties file or
2) How can I write B that it is created with Spring?
Some background information:
- I didn’t wrote the initial code so I don’t want to change too much but want to modify it so it can be maintained better in the future
- I don’t have that much Spring knowledge and only start getting more and more familiar with it.
- In point 2) I’m struggling because of the constructorand how to set it via Spring…
Any help would be appreciated
Advertisement
Answer
Here’s an example of using @ConfigurationProperties
to bind your application.properties
to a POJO.
Say you have a application.properties
file like this,
mail.hostname=mailer@mail.com mail.port=9000
You can create a POJO like this for the above scenario.
(Note: If your spring boot version is lower than 2.2 you might want to annotate this class with @Configuration
and @Component
as well)
@ConfigurationProperties(prefix = "mail") public class ConfigProperties { private String hostname; private String port; // Create Getters and Setters }
When the spring boot application initializes, it will automatically map values from application.properties
into this POJO. If you want to use this, all you have to do is create a variable and mark it with @Autowire
@Component public class TestClass { @Autowire private ConfigProperties properties; public void printSomething() { System.println(properties.getHostname()); System.println(properties.getPort()); } }
Following up on your question…
Since the class in your example is not managed by spring, and you have to keep it this way for some reason, you can use the following helper class to manually autowire a spring bean in a non spring managed class.
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Service; @Service public class BeanUtil implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; } /** *Use this method to manually autowire Spring Beans into classes that are not managed by Spring. * *@param beanClass - Class type of the required bean. **/ public static <T> T getBean(Class<T> beanClass) { return context.getBean(beanClass); } }
To use this in your class B
do the following.
public class B { private ConfigProperties properties; public B() { BeanUtil.getBean(ConfigProperties.class); // This will initialize properties variable properly. } public void printSomething() { System.println(properties.getHostname()); System.println(properties.getPort()); } }