Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing spring beans in static method

Tags:

java

spring

People also ask

How Spring beans are used in static methods?

If we want to use spring bean ref in static methods we need to use ApplicationContextAware interface and override setApplicationContext() and make context object as static.

Can @bean methods be static?

By marking this method as static , it can be invoked without causing instantiation of its declaring @Configuration class, thus avoiding the above-mentioned lifecycle conflicts. Note however that static @Bean methods will not be enhanced for scoping and AOP semantics as mentioned above.


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;
  }

}

This worked for me.

Define your bean using xml configuration (old school):

<bean id="someBean1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName"><value>${db.driver}</value></property>     
    <property name="url"><value>${db.url}</value></property>
    <property name="username"><value>${db.username_seg}</value></property>
    <property name="password"><value>${db.password_seg}</value></property>
</bean> 

Or define it with java instead xml (new school)

@Bean(name = "someBean2")
public MySpringComponent loadSomeSpringComponent() {

  MySpringComponent bean = new MySpringComponent();
  bean.setSomeProperty("1.0.2");
  return bean;
}

Accessing spring bean in static method

import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

public class TestUtils {

  public static void getBeansFromSpringContext() {
    WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
    //for spring boot apps
    //ApplicationContext context = SpringApplication.run(Application.class, args)
    DataSource datasource  = (DataSource)context.getBean("someBean1");
    MySpringComponent springBean  = (MySpringComponent)context.getBean("someBean2");
  }
}   

HTH