Accessing spring beans in static method
I have a Util class with static methods. Inside my Util class, I want to use spring beans so I included them in my util class. As far as I know it's not a good practice to use spring beans as static fields. But is there any way to access spring beans in a static method?
My example:
public class TestUtils {
private static TestBean testBean;
public void setTestBean(TestBean testBean) {
TestUtils.testBean = testBean;
}
public static String getBeanDetails() {
return beanName = testBean.getDetails();
}
}
I have seen in many forums that this is not a best practice. Can someone show me how I can handle this type of scenario?
My configuration file:
<bean id="testUtils" class="com.test.TestUtils">
<property name="testBean" ref="testBean" />
</bean>
My approach is for the bean one wishes to access to implement InitializingBean
or use @PostConstruct
, and containing a static reference to itself.
For example:
@Service
public class MyBean implements InitializingBean {
private static MyBean instance;
@Override
public void afterPropertiesSet() throws Exception {
instance = this;
}
public static MyBean get() {
return instance;
}
}
Usage in your static class would therefore just be:
MyBean myBean = MyBean.get();
This way, no XML configuration is required, you don't need to pass the bean in as a constructor argument, and the caller doesn't need to know or care that the bean is wired up using Spring (i.e., no need for messy ApplicationContext
variables).
The result of static methods should depend ONLY on the parameters passed into the method, therefore there is no need to call any bean.
If you need to call another bean then your method should be a member method of a standalone bean.
Other answers give you working solutions, but the fact it can be done doesn't mean that it should be done.
you may also implement ApplicationContextAware interface, like this:
@Component
public class TestUtils implements ApplicationContextAware {
private static ApplicationContext ac;
public static String getBeanDetails() {
return beanName = ((TestBean) ac.getBean("testBean")).getDetails();
}
@Override
public void setApplicationContext(ApplicationContext ac) {
TestUtils.ac = ac;
}
}