À l'aide de tx:annotation-driven empêche permettra à l'autowiring un haricot

Je suis au point un module sur un OSGi application, à l'aide de Spring MVC et de la Vierge Serveur.

Sur mon module j'ai un Contrôleur, que l'accès à un Gestionnaire, qui dispose d'une liste de gestionnaires qui sont responsables de la manipulation de génération de rapport.

Tout va bien, jusqu'à ce que j'ai dû appeler une méthode d'un service externe. Comme aucun de mes classes étaient de nature transactionnelle j'ai dû ajouter les références à l'opération de gestionnaire et de annotation-driven. Ensuite, mon Manager a cessé d'être informé.

Je comprends que lors de l'utilisation de annotation-driven tous mes haricots doivent implémenter une interface publique pour l'utilisation de proxy mécanisme de travail. Et autant que je sache, toutes les classes sont (l'un d'eux ne l'était pas, mais alors je l'ai changé).

Mes fichiers de configuration sont:

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>

et mon bundle-osgi.xml est comme suit:

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

Donc, après tous les services sont en cours de publication la oSGIChangeReportHandler.le registre est appelé (je suis capable de 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);
    }


}

Et bien que le débogueur affiche des Procurations pour deux le reportManager et reportHandler sur le register méthode, le débogueur ne pas s'arrête sur la ReportManagerImpl.addReportHandler méthode:

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

}

Je dois souligner que lorsque je supprime les tx:annotation-driven tag de la bundle-context.xml fichier, tout fonctionne bien (le handler est correctement ajouté à la liste pendant le démarrage).

Donc, ce qui me manque ici?

Est reportManager null dans oSGIChangeReportHandler.register?
Non! Il montre un objet proxy sur le débogueur. Mais j'ai résolu le problème, la réponse est ci-dessous. Merci pour le commentaire, tho. 🙂

OriginalL'auteur Alvaro Cavalcanti | 2013-07-02