2013-07-02 10 views
5

Zajmuję się tworzeniem modułu na aplikacji OSGi, przy użyciu Spring MVC i Virgo Webserver.Używanie tx: adnotacja sterowana zapobiega Autowiring fasoli

Na moim module mam kontroler, który ma dostęp do menedżera, który ma listę procedur obsługi odpowiedzialnych za generowanie raportów.

Wszystko działo się dobrze, dopóki nie musiałem wywoływać metody transakcyjnej z usługi zewnętrznej. Ponieważ żadna z moich klas nie była transakcyjna, musiałem dodać odniesienia do menedżera kontroli i annotation-driven. Następnie mój menedżer przestał otrzymywać powiadomienia.

Rozumiem, że podczas korzystania z annotation-driven wszystkie moje komponenty bean muszą implementować publiczny interfejs, aby mechanizm proxy działał. O ile mi wiadomo, wszystkie zajęcia są (jedna z nich nie była, ale potem ją zmieniłem).

Moje pliki konfiguracyjne są:

odnogi pęczka 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> 

i mój odnogi pęczka osgi.xml się następująco:

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

Więc, mimo wszystko usługi są publikowane oSGIChangeReportHandler.register jest wywoływany (jestem w stanie go debbugować):

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


} 

I chociaż debugger pokazuje proxy dla obu reportManager i reportHandler na metodzie register, debuger nie zatrzymuje się na metodzie 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); 
     } 
    } 

} 

Muszę podkreślić, że kiedy usunąć tag tx:annotation-driven z pliku bundle-context.xml wszystko działa poprawnie (handler jest poprawnie dodany do listy podczas uruchamiania).

Więc czego tu brakuje?

+0

jest 'reportManager' null w 'oSGIChangeReportHandler.register'? – Avi

+0

Nie! Pokazuje obiekt proxy w debugerze. Ale rozwiązałem problem, odpowiedź jest poniżej. Dzięki za komentarz, tho. :) –

Odpowiedz

2

Problem rozwiązany!

Jak widać na powyższym kodzie, definiowałem fasolę zarówno poprzez XML, jak i Annotation, w ten sposób każdy komponent bean został zduplikowany w środowisku wykonawczym. Następnie, po dodaniu znacznika tx:annotation-driven, aplikacja rozpoczęła przechwytywanie niewłaściwego komponentu bean. Rzeczywiście powiadamiano o fasoli, ale o sieroce.