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?
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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Problem gelöst!
Wie Sie sehen können auf meinen code oben, ich war die Festlegung der Bohnen sowohl über
XML
undAnnotation
werden, damit jede Bohne dupliziert wurde in der Laufzeit. Dann, wenn ich fügte hinzu, dietx:annotation-driven
tag der Anwendung begonnen, das abfangen der falschen Bohne. Es war in der Tat der Meldung einer bean, sondern ein Waisenkind bean.InformationsquelleAutor Alvaro Cavalcanti
Heres ein Beispiel der Arbeit mit tx. Suchen Sie diese Zeile:
xmlns:tx="http://www.springframework.org/schema/tx"
sind und dieser auf schemaLocation:
http://www.springframework.org/schema/tx/spring-tx.xsd
Quelle:
http://www.springbyexample.org/examples/hibernate-transaction-annotation-config.html
InformationsquelleAutor WiLLStenico