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?
jest 'reportManager' null w 'oSGIChangeReportHandler.register'? – Avi
Nie! Pokazuje obiekt proxy w debugerze. Ale rozwiązałem problem, odpowiedź jest poniżej. Dzięki za komentarz, tho. :) –