powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Заинжектить репозиторий в другой модуль
15 сообщений из 15, страница 1 из 1
Заинжектить репозиторий в другой модуль
    #39610451
fplab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго утра, коллеги!
Понимаю, что вопрос простой, но туплю безбожно :(
Приложение состоит из модулей, один из которых - реализация операций с РСУБД. Он сделан, как говорится, по учебнику:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
package com.rdbs.impl;
...
@Repository("domainDao")
public class DomainDaoImpl implements DomainDao {
    private static final Logger LOG = LoggerFactory.getLogger(DomainDaoImpl.class);

    // Hibernate-JPA entity manager
    @PersistenceContext
    private EntityManager entityManager;

    @Transactional(readOnly=true)
    @Override
    public Persons findPersonsById(long id) {
        LOG.info("[RDBS] findPersonsById: {}", id);
        TypedQuery<Persons> query = entityManager.createNamedQuery("findPersonsById", Persons.class);
        query.setParameter("id", id);

        return query.getSingleResult();
    }
    ...
}


Все работает отлично.
Задача состоит в том, чтобы заинжектить этот репозиторий в другой модуль. Пишу в его конфиге:
Код: xml
1.
2.
3.
4.
...
<context:annotation-config/>
<bean id="domainDao" class="com.rdbs.impl.DomainDaoImpl"/>
...


и далее
Код: java
1.
2.
3.
4.
5.
6.
package com.app.worker;
...
public class Extractor {
    @Resource(name = "domainDao")
    private DomainDao domainDao;
    ...



После вызова domainDao.findPersonsById(...) получаю NPE. В каком месте я дурак?
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39610484
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fplabdomainDao.findPersonsById(...)а зачем это писать руками, да еще именоваными запросами?
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39610487
fplab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123,

Модуль работы с РСУБД существующий. Написан достаточно давно и используется в нескольких проектах. Его надо проинжектить в новый проект.
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39610498
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fplab,

А почем через @Resource, а не @Autowired @Qualifier("domainDao")?
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39610575
fplab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgul,
Спасибо. Работает. Но приходится явно загружать контекст:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
package com.app.worker;
...
public class Extractor {
    @Autowired
    @Qualifier("domainDao")
    private DomainDao domainDao;

    public Extractor() {
        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
        ctx.load("classpath:META-INF/worker-context.xml");
        ctx.refresh();

        domainDao = ctx.getBean("domainDao", DomainDao.class);
    }
...
}


Более того, при таком подходе аннотации вообще можно убрать и будет работать. А вот этого делать и не хочется. Хочется, чтобы связывание выполнялось без принудительной загрузки контекста. Это возможно как-нибудь сделать? Вот содержимое worker-context.xml:
Код: xml
1.
2.
3.
4.
5.
    <!-- Context: scanning -->
    <context:component-scan base-package="com.app.worker"/>
    <context:annotation-config/>

    <import resource="rdbs-context.xml"/>



где импортируется конфигурация модуля подключения к БД и в котором определен класс DomainDaoImpl который и надо проинжектить. Спасибо!
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39610663
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fplab,

Так правильно у вас класс Extractor похоже вне spring-контекста.

Добавьте создание extractor'а в worker-context.xml
Будет автоматически инжектится.

:-)
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39610727
fplab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgul,
Нет, определенно не мой день :( Спасибо за совет, но вот как это сделать... Вот контекст:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
    <!-- Context: scanning -->
    <context:component-scan base-package="com.app.worker"/>
    <context:annotation-config/>

    <import resource="rdbs-context.xml"/>

    <bean id="domainDao" class="com.rdbc.impl.DomainDaoImpl"/>

    <bean id="extractor" class="com.app.Extractor"/>



и получаю, что нужный мне domainDao все равно null. Класс Extractor аннотировал всем чем можно - не инжектится. Конструктор класса аннотировал - не инжектится. Подскажите, пожалуйста, еще раз - куда глянуть. Спасибо и извините за беспокойство!
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39610958
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fplab,

Если не трудно покажите где вы используете Extractor.
По идее там где он используется его тоже надо инжектить.
Тогда он будет создаваться в рамках контекста и заинжектит все что надо.

Т.к. во время подымания контектса он вам не ругается, что "DomainDao domainDao" не заижектен, то это значит, что вы сами создаете объект типа Extractor.

Что делать не рекомендуется.
Грубо говоря все объекты-бины не надо создавать ручками (через new).
Т.к. spring-context об этих объектах ничего не знает и их не видит.

P.S. ИМХО вам бы почитать что такое spring-context, жизненный цикл бинов, и как со всем этим работать.
Прошу прощения у меня складывается впечатление, что вы делаете не совсем понимая, что делаете.
Из-за этого у вас вылазят странности.
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39610979
fplab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgul,
В общем-то да - глЫбины понимания нет. Но надо переработать старый проект, а автора уже не найти :)
Значит так. Сначала реализация DAO:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
package com.rdbs.impl;

@Service("domainDao")
@Repository
@Transactional
public class DomainDaoImpl implements DomainDao {
    private static final Logger LOG = LoggerFactory.getLogger(DomainDaoImpl.class);

    // Hibernate-JPA entity manager
    @PersistenceContext
    private EntityManager entityManager;

    @Transactional(readOnly=true)
    @Override
    public Persons findPersonsById(long id) {
        LOG.info("[RDBS] findPersonsById: {}", id);
        TypedQuery<Persons> query = entityManager.createNamedQuery("findPersonsById", Persons.class);
        query.setParameter("id", id);

        return query.getSingleResult();
    }

    // Другие методы
    ...
}



DomainDao - как обычно - интерфейс с описаниями:
Код: java
1.
2.
3.
4.
5.
6.
package com.rdbs.dao;

public interface DomainDao {
    Persons findPersonsById(long id);
    ...
}



Сущность:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
package com.rdbs.entity;

@Entity
@Table(name="persons")
@Access(AccessType.FIELD)
@NamedQueries({
        @NamedQuery(name="findPersonsById", query="SELECT p FROM Persons p WHERE p.id = :id"),
        ...
})
public class Persons implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    ...

    // Сеттеры, геттеры
}


Контекст - стандартный XML (rdbs-context.xml) с описанием DataSource, EntityManagerFactory, TransactionManager и свойствами подключения к БД (хост, порт, драйвер и проч).
Здесь все работает - проверено железно и не раз.
Итак, мне надо инжектировать domainDao в класс:
Код: java
1.
2.
3.
4.
5.
6.
7.
@Service("extractor")
public class Extractor {
    @Autowired
    @Qualifier("domainDao")
    private DomainDao domainDao;
    ...
}


и "дернуть" из него методы findPersonsXXX. Контекст:
Код: xml
1.
2.
3.
4.
5.
6.
7.
    <!-- Context: scanning -->
    <context:component-scan base-package="..."/>
    <context:annotation-config/>

    <import resource="rdbs-context.xml"/>

    <bean id="domainDao" class="com.rdbs.impl.DomainDaoImpl"/>


Но при таком раскладе domainDao не инжектится - получаю null.
Кажется, ничего не забыл :) Спасибо
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39611035
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fplab,

Как и где класс Extractor вызываете?
Можно код.
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39611061
fplab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgul,
А ведь, кажется, что-то сделал :) Инжектится. Вы заставили подумать и почитать - СПАСИБО!!! Вот код:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
public class Scanner {
    private Extractor extractor;
    private DomainDao domainDao;

    public Scanner() {
        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
        ctx.load("classpath:META-INF/worker-context.xml");
        ctx.refresh();

        // Извлекаем и внедряем
        extractor = ctx.getBean("extractor", Extractor.class);
        domainDao = extractor.getDomainDao();

        // Проверяем
        System.out.println(extractor);
        System.out.println(domainDao);
    }
}



Насколько правильно ТАК писать? И сразу вопрос: можно ли прочесть контекст без GenericXMLApplicationContext и ему подобных?
Еще раз - спасибо
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39611077
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fplab,

Не правильно же :-)
Сканер то же нужно загнать в bean, например через @Context

А потом придется узнавать где используется класс Scanner, и так далее до функции "main" :-)

Зачем вы самостоятельно что-то извлекаете из spring-контекста?

ИМХО тогда вообще избавиться от Spring'а и все инжектить через передачу параметров в конструктор.
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39611082
fplab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgul,
Что такое @Context? Аннотация? Нигде в документации такого не нашел
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39611188
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fplab,

Прошу прощения ошибся, конечно же @Component :-)
...
Рейтинг: 0 / 0
Заинжектить репозиторий в другой модуль
    #39611325
fplab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mad_nazgul,

Спасибо. Поразмышляю...
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Заинжектить репозиторий в другой модуль
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]