Добавление предварительно созданного боба к контексту приложения Spring

Python и pymongo

Поиск объектов между двумя датами в Python с pymongo в коллекции posts (на основе учебника ):

from_date = datetime.datetime(2010, 12, 31, 12, 30, 30, 125000)
to_date = datetime.datetime(2011, 12, 31, 12, 30, 30, 125000)

for post in posts.find({"date": {"$gte": from_date, "$lt": to_date}}):
    print(post)

Где {"$gte": from_date, "$lt": to_date} указывает диапазон в терминах типов datetime.datetime.

23
задан Adam Paynter 30 January 2009 в 18:52
поделиться

4 ответа

Я обнаружил, что два интерфейса Spring могут использоваться для реализации то, в чем я нуждаюсь. интерфейс BeanNameAware позволяет Spring говорить объекту свое имя в контексте приложения путем вызова setBeanName (Строка) метод. интерфейс FactoryBean говорит Spring не использовать сам объект, а скорее объект, возвращенный, когда getObject () метод вызывается. Соедините их, и Вы добираетесь:

public class PlaceholderBean implements BeanNameAware, FactoryBean {

    public static Map<String, Object> beansByName = new HashMap<String, Object>();

    private String beanName;

    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    @Override
    public Object getObject() {
        return beansByName.get(beanName);
    }

    @Override
    public Class<?> getObjectType() {
        return beansByName.get(beanName).getClass();
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

}

бобовое определение теперь уменьшается до:

<bean id="dataSource" class="PlaceholderBean" />

заполнитель получает свое значение прежде, чем создать контекст приложения.

public void run(DataSource externalDataSource) {
    PlaceholderBean.beansByName.put("dataSource", externalDataSource);
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    assert externalDataSource == context.getBean("dataSource");
}

Вещи, кажется, работают успешно!

15
ответ дан Adam Paynter 29 November 2019 в 01:33
поделиться

Можно создать класс обертки для DataSource, который просто делегирует к содержавшему DataSource

public class DataSourceWrapper implements DataSource {

DataSource dataSource;

public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
}

@Override
public Connection getConnection() throws SQLException {
    return dataSource.getConnection();
}

@Override
public Connection getConnection(String username, String password)
        throws SQLException {
    return dataSource.getConnection(username, password);
}
//delegate to all the other DataSource methods
}

Затем в Вас файл контекста Spring, Вы объявляете DataSourceWrapper и соединяете его проводом во все свои бобы. Затем в Вашем методе Вы получаете ссылку на DataSourceWrapper и устанавливаете перенесенный DataSource на тот, переданный в к Вашему методу.

Эта вся работа высоко зависится от того, что происходит в Вашем файле контекста Spring когда то, что это было загруженным. Если боб требует, чтобы DataSource уже был доступен, когда контекст загружается затем, Вам, вероятно, придется записать BeanFactoryPostProcessor, который изменяет файл контекста Spring, поскольку он загружается, скорее затем делая вещи после загрузки (хотя, возможно, ленивое-init могло решить эту проблему).

1
ответ дан Patrick 29 November 2019 в 01:33
поделиться

При создании объекта путем называния "новым" он не находится под контролем фабрики Spring.

, Почему бы не Spring вводят DataSource в объект вместо того, чтобы передать его в выполненный ()?

0
ответ дан duffymo 29 November 2019 в 01:33
поделиться

Я был в точно такой же ситуации. Поскольку никто не предложил моего решения (и я думаю, что мое решение более элегантно), я добавлю его сюда для будущих поколений :-)

Решение состоит из двух шагов:

  1. создать родительский ApplicationContext и зарегистрировать в нем существующий bean.
  2. создать дочерний ApplicationContext (передать в родительский контекст) и загрузить бобы из XML файла

Шаг #1:

//create parent BeanFactory
DefaultListableBeanFactory parentBeanFactory = new DefaultListableBeanFactory();
//register your pre-fabricated object in it
parentBeanFactory.registerSingleton("dataSource", dataSource);
//wrap BeanFactory inside ApplicationContext
GenericApplicationContext parentContext = 
        new GenericApplicationContext(parentBeanFactory);
parentContext.refresh(); //as suggested "itzgeoff", to overcome a warning about events

Шаг #2:

//create your "child" ApplicationContext that contains the beans from "beans.xml"
//note that we are passing previously made parent ApplicationContext as parent
ApplicationContext context = new ClassPathXmlApplicationContext(
        new String[] {"beans.xml"}, parentContext);
32
ответ дан 29 November 2019 в 01:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: