Динамический выбор весенней загрузки TransactionManager - PullRequest
0 голосов
/ 28 июня 2018

Я преобразую свое существующее приложение Spring в приложение Spring Boot. В моем существующем приложении нам необходимо подключиться к нескольким базам данных, и мы достигли этого, определив несколько источников данных и выбрав соответствующий компонент на основе условия. Менеджер транзакций также был выбран с помощью пользовательской реализации TransactionInterceptor.

@Override
public TransactionAttributeSource getTransactionAttributeSource() {
    final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource();
    return new TransactionAttributeSource() {

        @Override
        public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) {
            TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass);
            String database = (String) ThreadContext.get("database");
            if (database != null && StringUtils.isNotBlank(database)) {
                if (txAttr instanceof DefaultTransactionAttribute) {
                    ((DefaultTransactionAttribute) txAttr).setQualifier("txManager" + database);
                }
            }
            return txAttr;
        }
    };
}

Через BeanFactoryPostProcessor мы включили этот перехватчик

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
         String[] names = beanFactory.getBeanNamesForType(TransactionInterceptor.class);
        for (String name : names) {
            BeanDefinition bd = beanFactory.getBeanDefinition(name);
            bd.setBeanClassName(MyTransactionInterceptor.class.getName());

        }
}

Это отлично работало в Spring 4.X.

Теперь, когда мы движемся к Spring Boot, я пытаюсь использовать тот же подход. Я вижу, что вызывается фабрика бинов, но я не нахожу вызовов, происходящих с классом Custom Interceptor. Это приводит к тому, что мой @Transactional терпит неудачу, поскольку существует более одного квалифицируемого компонента.

Я что-то упустил из-за конфигурации Spring Boot?

(Этот подход динамического управления транзакциями был через справочный блог http://blog.tirasa.net/dynamic-springs--at-transactional.html)

1 Ответ

0 голосов
/ 29 июня 2018

Окончательным ответом оказалось установление фабричных классов и имени фабричного компонента равным нулю, что привело к вызову перехватчика транзакции. Мне еще предстоит выяснить, как это влияет на вызов перехватчика, как со значениями в этих полях (они указывают на классы ProxyTransaction, так как он создает компонентactionInterceptor).

Окончательный код был в форме -

Класс TransactionInterceptor

@Component
public class TransactionInterceptorReplacer implements BeanFactoryPostProcessor {

@Override
    public void postProcessBeanFactory(final ConfigurableListableBeanFactory factory) throws BeansException {
        String[] names = factory.getBeanNamesForType(TransactionInterceptor.class);
        for (String name : names) {
            BeanDefinition bd = factory.getBeanDefinition(name);
            bd.setBeanClassName(MyTransactionInterceptor.class.getName());
            bd.setFactoryBeanName(null);
            bd.setFactoryMethodName(null);
       }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...