Mit tx:annotation-driven verhindert Autowiring eine Bohne

Entwickle ich ein Modul auf einer OSGi-Anwendung mit Spring MVC und Jungfrau Webserver.

Auf meinem Modul habe ich einen Controller, access Manager, die eine Liste von Handlern, die sind zuständig für die Bearbeitung von berichten.

Alles war gut, bis ich musste Aufruf einer transaktionalen Methode über einen externen Dienst. Da keiner meiner Klassen waren Transaktions-ich hatte, um die Verweise auf die transation manager und annotation-driven. Dann, mein Manager ist nicht mehr benachrichtigt.

Ich verstehe, dass bei der Verwendung von annotation-driven alle meine Bohnen implementieren muss, um eine öffentliche Schnittstelle um für das proxying-Mechanismus funktioniert. Und soweit ich weiß, alle Klassen sind (einer von Ihnen war nicht, aber dann habe ich es geändert).

Meine Konfigurationsdateien sind:

bundle-context.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>

und meine bundle-osgi.xml ist wie folgt:

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

So, nach all den services veröffentlicht werden, die oSGIChangeReportHandler.registrieren aufgerufen wird (ich bin in der Lage, debbug):

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


}

Und obwohl der debugger zeigt Proxys, die sowohl für die reportManager und reportHandler auf die register Methode, der debugger nicht die halte auf der ReportManagerImpl.addReportHandler Methode:

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

}

Muss ich betonen, dass, wenn ich entfernen Sie die tx:annotation-driven tag aus der bundle-context.xml - Datei, funktioniert alles einwandfrei (die handler ist richtig Hinzugefügt, um die Liste während des Startvorgangs).

So, was übersehe ich hier?

Ist reportManager null in oSGIChangeReportHandler.register?
Nein! Es zeigt ein proxy-Objekt auf den debugger. Aber ich habe das problem gelöst, die Antwort ist unten. Danke für den Kommentar, tho. 🙂

InformationsquelleAutor Alvaro Cavalcanti | 2013-07-02

Schreibe einen Kommentar