Подтвердить что ты не робот

Доступ к spring beans в статическом методе

У меня есть класс Util со статическими методами. Внутри моего класса Util я хочу использовать spring beans, поэтому включил их в мой класс util. Насколько я знаю, не рекомендуется использовать spring beans как статические поля. Но есть ли способ доступа к spring beans в статическом методе?

Мой пример:

public class TestUtils {

   private static TestBean testBean;

   public void setTestBean(TestBean testBean) {
     TestUtils.testBean = testBean;
   }

  public static String getBeanDetails() {
    return beanName = testBean.getDetails();
  }
}

Я видел на многих форумах, что это не лучшая практика. Может ли кто-нибудь показать мне, как я могу справиться с этим типом сценария?

Мой конфигурационный файл:

<bean id="testUtils" class="com.test.TestUtils">
 <property name="testBean" ref="testBean" />
</bean>
4b9b3361

Ответ 1

Мой подход для bean хочет получить доступ к реализации InitializingBean или использовать @PostConstruct и содержащий статическую ссылку на себя.

Например:

@Service
public class MyBean implements InitializingBean {
    private static MyBean instance;

    @Override
    public void afterPropertiesSet() throws Exception {
        instance = this;
    }

    public static MyBean get() {
        return instance;
    }
}

Использование в вашем статическом классе было бы просто:

MyBean myBean = MyBean.get();

Таким образом, XML-конфигурация не требуется, вам не нужно передавать bean в качестве аргумента конструктора, и вызывающему абоненту не нужно знать или заботиться о том, чтобы bean был подключен, используя Spring (т.е. нет необходимости в беспорядочных переменных ApplicationContext).

Ответ 2

вы также можете реализовать ApplicationContextAware интерфейс, например:

@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) {
    this.ac = ac;
  }

}

Ответ 3

Результат статических методов должен зависеть ТОЛЬКО от параметров, переданных в метод, поэтому нет необходимости вызывать любой bean.

Если вам нужно вызвать другой bean, тогда ваш метод должен быть методом участника автономного bean.

Другие ответы дают вам рабочие решения, но тот факт, что это может быть сделано, не означает, что это должно быть сделано.

Ответ 4

Подобно ответу @nullPainter, но мы сделали следующее. Никакой постконструктивной логики не требуется. Он просто устанавливает статический член непосредственно во время инъекции (в методе @Autowired).

@Service
public class MyUtil {

    private static MyManager myManager;

    @Autowired(required = true)
    public void setMyManager(MyManager manager) {
        myManager = manager;
    }

    public static MyManager getMyManager() {
        return myManager;
    }
}

Ответ 5

Это сработало для меня.

Определите свой bean-компонент, используя конфигурацию xml (старая школа):

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

Или определите это с помощью Java вместо XML (новая школа)

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

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

Доступ к пружинному бобу статическим методом

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

public class TestUtils {

  public static void getBeansFromSpringContext() {
    WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
    DataSource datasource  = (DataSource)context.getBean("someBean1");
    MySpringComponent springBean  = (MySpringComponent)context.getBean("someBean2");
  }
}   

НТН

Ответ 6

Вот как я ввел из spring для статического поля.

<bean id="..." class="...">
 <property name="fieldToBeInjected">
            <util:constant static-field="CONSTANT_FIELD" />
        </property>
</bean>

Возможно, это тоже поможет вам.

Ответ 7

Подход, который вы наметили, - это то, что, как я видел, используется для ввода Spring bean в класс утилиты.

<bean id="testUtils" class="com.test.TestUtils">
 <property name="testBean" ref="testBean" />
</bean>

Другой вариант:

<bean name="methodInvokingFactoryBean" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="TestUtils.setInstance"/>
        <property name="arguments">
            <list>
                <ref bean="testBean"/>
            </list>
       </property>
</bean>

с:

public class TestUtils {

   private static testBean;

   public static void setInstance(TestBean anInstance) {
     testBean = anInstance;
   }

  public static String getBeanDetails() {
    return testBean.getDetails();
  }
}

Подробнее здесь и здесь