как получить транзакцию, поддерживающую прокси из контекста приложения Spring? - PullRequest
1 голос
/ 21 февраля 2012

Мне нужно использовать bean-компонент из контекста Spring, а не bean-компонент, управляемый Spring, поэтому я делаю следующее: аннотируйте bean-компонент с помощью аннотации @Service, поэтому экземпляр bean-компонента создается во время весенней загрузки.

<bean id="customRevisionListener" class="ru.csbi.registry.services.impl.envers.CustomRevisionListener" />

Этот экземпляр является ApplicationContextAware, поэтому контекст приложения внедряется в этот экземпляр компонента, и я сохраняю его в статическую переменную:

@Service 
public class CustomRevisionListener implements EntityTrackingRevisionListener, ApplicationContextAware {

private static ApplicationContext applicationContext;

private ModelInformationService modelInformationService;    

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    CustomRevisionListener.applicationContext = applicationContext;
}

private ModelInformationService getModelInformationService() {
    if (modelInformationService == null) {
        modelInformationService = applicationContext.getBean(ModelInformationService.class);
    }
//      TransactionProxyFactoryBean
    return modelInformationService;
}

После этого еще один экземпляр CustomRevisionListener создается в не пружинном контексте (hibernate envers context). Здесь я использую статическую переменную для получения весны applicationContext

после этого я получаю бины из контекста приложения:

private ModelInformationService getModelInformationService() {
if (modelInformationService == null) {
    modelInformationService = applicationContext.getBean(ModelInformationService.class);
}

проблема в том, что у этого компонента есть все свойства @Autowired, введенные правильно:

 @Service
 public class ModelInformationServiceImpl implements ModelInformationService {

@Autowired
private EntityChangeService entityChangeService; // injected correctly

@Autowired
private PropertyService propertyService; // injected correctly

@Autowired
private ru.csbi.registry.services.reflection.HibernateDomainService hibernateService; // injected correctly

, но они являются простыми экземплярами классов Java, а не Прокси, поддерживающими аннотацию @Transactional, как для моего обычного весеннего кода:

 getModelInformationService().getClass().getName() is "ru.csbi.registry.services.impl.envers.ModelInformationServiceImpl"

и должно быть что-то вроде

$Proxy71

Как получить прокси, поддерживающие транзакции, которые генерирует spring, например, при внедрении bean-компонентов в @Controller, в bean-компонент, не управляемый spring?

я использую следующую конфигурацию весны:

<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
    <constructor-arg ref="lazyConnectionDataSourceProxy"/>
</bean>

<bean id="lazyConnectionDataSourceProxy" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
    <property name="targetDataSource">
        <ref local="dataSourceTarget" />
    </property>
</bean>

<bean id="dataSourceTarget" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${ds.driver}" />
    <property name="url" value="${ds.url}" />
    <property name="username" value="${ds.user}" />
    <property name="password" value="${ds.password}" />
    <property name="initialSize" value="${ds.initialSize}" />
    <property name="maxActive" value="${ds.maxActive}" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
    <property name="dataSource" ref="dataSource" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <!--property name="entityInterceptor">
        <bean class="ru.csbi.registry.utils.audit.AuditLogInterceptor">
            <property name="sessionFactory" ref="auditSessionFactory" />
        </bean>
    </property-->
    <property name="dataSource" ref="dataSource" />
    <property name="lobHandler" ref="oracleLobHandler" />
    <property name="packagesToScan" value="ru.csbi.registry.domain" />
    <property name="hibernateProperties">
        <bean id="hibernatePropertiesFactoryBean" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
            <property name="locations">
                <list>
                    <value>file:${realtyregistry.settings.path}/hibernate-config.properties</value>
                </list>
            </property>
        </bean>
    </property>

    <property name="eventListeners">
        <map>
            <entry key="post-insert" value-ref="auditEventListener" />
            <entry key="post-update" value-ref="auditEventListener" />
            <entry key="post-delete" value-ref="auditEventListener" />
            <entry key="pre-collection-update" value-ref="auditEventListener" />
            <entry key="pre-collection-remove" value-ref="auditEventListener" />
            <entry key="post-collection-recreate" value-ref="auditEventListener" />
        </map>
    </property>
</bean>

<bean id="auditEventListener" class="org.hibernate.envers.event.AuditEventListener" />

<bean id="persistenceManagerHibernate" class="ru.csbi.registry.utils.PersistenceManagerHibernate">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
...