Использование tx: управляемый аннотациями предотвращает автоматическое подключение Боба


Я разрабатываю модуль для приложения OSGi, используя Spring MVC и Virgo Webserver.

В моем модуле есть контроллер, который обращается к менеджеру, у которого есть список обработчиков, ответственных за обработку генерации отчетов.

Все шло прекрасно, пока мне не пришлось вызывать транзакционный метод из внешнего сервиса. Поскольку ни один из моих классов не был транзакционным, мне пришлось добавить ссылки на transation manager и annotation-driven. Затем мой менеджер перестал быть предупрежденный. Я понимаю, что при использовании annotation-driven Все мои бобы должны реализовать открытый интерфейс, чтобы механизм проксирования работал. И насколько я знаю, все классы есть (один из них не был, но потом я его изменил).

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

Связка-контекст.XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="reportManager" class="reportmodule.manager.impl.ReportManagerImpl"/>
<bean id="mvpepReportHandler" class="reportmodule.manager.impl.MVPEPReportHandler"/>
<bean id="reportConfigDao" class="reportmodule.repository.impl.ReportConfigurationHibernateDAOImpl"/>
<bean id="oSGIChangeReportHandler" class="reportmodule.osgi.impl.OSGIChangeReportHandlerImpl"/>
<bean id="reportController"
class="reportmodule.controller.impl.ReportControllerImpl"/>
<bean id="reportControllerHandlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>/module/reportController/**=reportController</value>
</property>
<property name="alwaysUseFullPath" value="true"></property>
</bean>
</beans>

И мой сверток-осги.xml выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.springframework.org/schema/osgi-compendium
http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium-1.2.xsd">

<osgi:reference id="transactionManager" interface="org.springframework.transaction.PlatformTransactionManager" />
<osgi:reference id="sessionFactory" interface="org.hibernate.SessionFactory" />
<osgi:reference id="smaCoreUtilService" interface="core.util.service.SmaCoreUtilService" />

<osgi:service ref="reportControllerHandlerMapping"
interface="org.springframework.web.servlet.HandlerMapping"
context-class-loader="service-provider"
auto-export="interfaces"/>

<osgi:service interface="reportmodule.api.manager.ReportManager" ref="reportManager" auto-export="interfaces"/>

<osgi:service interface="reportmodule.api.manager.ReportHandler" ref="mvpepReportHandler" auto-export="interfaces"/>

<osgi:service interface="reportmodule.repository.ReportConfigurationDAO" ref="reportConfigDao" auto-export="interfaces"/>

<osgi:service interface="reportmodule.osgi.OSGIChangeReportHandler" ref="oSGIChangeReportHandler" auto-export="interfaces"/>

<osgi:list cardinality="0..N" id="reportHandler" interface="reportmodule.api.manager.ReportHandler" greedy-proxying="true">
<osgi:listener ref="oSGIChangeReportHandler" bind-method="register" unbind-method="unregister"/>    
</osgi:list>

</beans>
Итак, после того, как все службы будут опубликованы, oSGIChangeReportHandler.Регистрация называется (Я умею debbug it):
@Service(value="oSGIChangeReportHandler")
public class OSGIChangeReportHandlerImpl implements OSGIChangeReportHandler {

    private ReportManager reportManager;

    /**
     * @param reportManager the reportManager to set
     */
    @Autowired
    public void setReportManager(ReportManager reportManager) {
        this.reportManager = reportManager;
    }

    @SuppressWarnings("rawtypes")
    public void register(ReportHandler reportHandler, Map properties) {
        reportManager.addReportHandler(reportHandler);
    }

    @SuppressWarnings("rawtypes")
    public void unregister(ReportHandler reportHandler, Map properties) {
        reportManager.removeReportHandler(reportHandler);
    }


}

И хотя отладчик показывает прокси как для reportManager, так и для reportHandler метода register, отладчик не останавливается на методе ReportManagerImpl.addReportHandler:

@Service(value="reportManager")
@Transactional(propagation = Propagation.MANDATORY, rollbackFor = Exception.class)
public class ReportManagerImpl implements ReportManager {

    private ReportConfigurationDAO reportConfigurationDAO;

    private ArrayList<ReportHandler> reportHandlers = new ArrayList<ReportHandler>();

    /**
     * @param reportConfigurationDAO the reportConfigurationDAO to set
     */
    @Autowired
    public void setReportConfigurationDAO(ReportConfigurationDAO reportConfigurationDAO) {
        this.reportConfigurationDAO = reportConfigurationDAO;
    }

    @Override
    @Transactional
    public InputStream gerarRelatorio(ReportRequest repoReq) throws NegocioException {
        // Generates the report...
    }

    /* (non-Javadoc)
     * @see reportmodule.api.manager.ReportManager#addReportHandler(reportmodule.api.manager.ReportHandler)
     */
    @Override
    public void addReportHandler(ReportHandler handler) {
        if (handler != null) {
            this.reportHandlers.add(handler);
        }
    }

    /* (non-Javadoc)
     * @see reportmodule.api.manager.ReportManager#removeReportHandler(reportmodule.api.manager.ReportHandler)
     */
    @Override
    public void removeReportHandler(ReportHandler handler) {
        if (handler != null) {
            this.reportHandlers.remove(handler);
        }
    }

}
Я должен подчеркнуть, что когда я удаляю тег tx:annotation-driven из файла bundle-context.xml, все работает нормально (handler правильно добавляется в список во время запуска).

Итак, что я здесь упускаю?

2 6

2 ответа:

Проблема решена!

Как вы можете видеть в моем коде выше, я определял бобы как через XML, так и через Annotation, таким образом, каждый боб был продублирован во время выполнения. Затем, когда я добавил тег tx:annotation-driven, приложение начало перехватывать неверный Боб. Это действительно был Боб, но Боб сироты.

Вот пример работы с tx. Посмотрите на эту линию: xmlns: tx="http://www.springframework.org/schema/tx"

И это на schemaLocation: http://www.springframework.org/schema/tx/spring-tx.xsd

Источник: http://www.springbyexample.org/examples/hibernate-transaction-annotation-config.html