2013-07-02 11 views
5

Ich entwickle ein Modul für eine OSGi-Anwendung mit Spring MVC und Virgo Webserver.Verwendung von tx: Annotation-Driven verhindert das Autowiren einer Bean

Auf meinem Modul habe ich einen Controller, der auf einen Manager zugreift, der eine Liste von Handlern enthält, die für die Berichterstellung zuständig sind.

Alles lief gut, bis ich eine Transaktionsmethode von einem externen Dienst aufrufen musste. Da keine meiner Klassen transaktional war, musste ich die Referenzen zum Transaktionsmanager und annotation-driven hinzufügen. Dann wurde mein Manager nicht mehr benachrichtigt.

Ich verstehe, dass bei Verwendung von annotation-driven alle meine Beans eine öffentliche Schnittstelle implementieren müssen, damit der Proxy-Mechanismus funktioniert. Und soweit ich weiß, sind alle Klassen (einer von ihnen war nicht, aber dann habe ich es geändert).

Meine Konfigurationsdateien sind:

bündel 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 mein Bündel-osgi.xml sich 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> 

, also nach allen Die Dienste werden veröffentlicht Das oSGIChangeReportHandler.register wird aufgerufen (ich kann es 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 Proxies für zeigt sowohl die reportManager und reportHandler auf dem register Methode, der Debugger stoppt nicht an 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); 
     } 
    } 

} 

Ich muss betonen, wenn ich entfernen Sie die tx:annotation-driven Tag Von der Datei bundle-context.xml funktioniert alles einwandfrei (die handler wird während des Startvorgangs ordnungsgemäß zur Liste hinzugefügt).

Also, was fehlt mir hier?

+0

Ist 'reportManager' null in 'oSGIChangeReportHandler.register'? – Avi

+0

Nein! Es zeigt ein Proxy-Objekt auf dem Debugger. Aber ich habe das Problem gelöst, die Antwort ist unten. Danke für den Kommentar, tho. :) –

Antwort

2

Problem gelöst!

Wie Sie in meinem Code oben sehen können, habe ich die Beans sowohl über XML als auch Annotation definiert, daher wurde jede Bean in Runtime dupliziert. Dann, als ich den Tag tx:annotation-driven hinzugefügt habe, begann die Anwendung, die falsche Bean abzufangen. Es war in der Tat eine Bean, aber eine Waise Bean.

Verwandte Themen