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
You can create a class that will allow access to any Bean from a static context. Most other answers here only show how to access a single class statically.
The Proxy in the code below was added in case someone calls the getBean() method before the ApplicationContext is autowired (as this would result in a nullpointer). None of the other solutions posted here handle that nullpointer.
Details on my blog: https://tomcools.be/post/apr-2020-static-spring-bean/
UserRepository userRepo = StaticContextAccessor.getBean(UserRespository.class)
@Component
public class StaticContextAccessor {
private static final Map classHandlers = new HashMap<>();
private static ApplicationContext context;
@Autowired
public StaticContextAccessor(ApplicationContext applicationContext) {
context = applicationContext;
}
public static T getBean(Class clazz) {
if (context == null) {
return getProxy(clazz);
}
return context.getBean(clazz);
}
private static T getProxy(Class clazz) {
DynamicInvocationhandler invocationhandler = new DynamicInvocationhandler<>();
classHandlers.put(clazz, invocationhandler);
return (T) Proxy.newProxyInstance(
clazz.getClassLoader(),
new Class[]{clazz},
invocationhandler
);
}
//Use the context to get the actual beans and feed them to the invocationhandlers
@PostConstruct
private void init() {
classHandlers.forEach((clazz, invocationHandler) -> {
Object bean = context.getBean(clazz);
invocationHandler.setActualBean(bean);
});
}
static class DynamicInvocationhandler implements InvocationHandler {
private T actualBean;
public void setActualBean(T actualBean) {
this.actualBean = actualBean;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (actualBean == null) {
throw new RuntimeException("Not initialized yet! :(");
}
return method.invoke(actualBean, args);
}
}
}