2013-07-02 7 views
5

Я разрабатываю модуль в приложении OSGi, используя Spring MVC и Web-сервер Virgo.Использование tx: annotation-driven предотвращает Autowiring bean

В моем модуле у меня есть контроллер, который получает доступ к диспетчеру, который имеет список обработчиков, ответственных за обработку генерации отчетов.

Все было в порядке, пока мне не пришлось вызывать транзакционный метод из внешней службы. Поскольку ни один из моих классов не был транзакционным, мне пришлось добавить ссылки на диспетчер трансакций и annotation-driven. Затем мой менеджер перестает быть уведомленным.

Я понимаю, что при использовании annotation-driven все мои компоненты должны реализовывать открытый интерфейс, чтобы механизм проксирования работал. И насколько я знаю, все классы (один из них не был, но потом я его изменил).

Мои файлы конфигурации:

пачке 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> 

и мой пачке osgi.xml выглядит следующим образом:

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

Так, в конце концов услуги публикуются oSGIChangeReportHandler.register (я могу его дебютировать):

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


} 

И хотя отладчик показывает Proxies для обоих reportManager и reportHandler по методу register, отладчик не останавливается на 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); 
     } 
    } 

} 

Я должен подчеркнуть, что, когда я удалить tx:annotation-driven тег из файла bundle-context.xml все работает нормально (handler правильно добавлен в список во время запуска).

Итак, что мне здесь не хватает?

+0

Является 'reportManager' null в 'oSGIChangeReportHandler.register'? – Avi

+0

Нет! Он показывает прокси-объект в отладчике. Но я решил проблему, ответ ниже. Спасибо за комментарий, tho. :) –

ответ

2

Проблема решена!

Как вы можете видеть на моем коде выше, я определял бобы как через XML, так и Annotation, таким образом, каждый бит был продублирован во время выполнения. Затем, когда я добавил тэг tx:annotation-driven, приложение начало перехватывать неправильный компонент. Это было действительно уведомление о фасоле, но о сироте.