All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.mats3.spring.jms.factories.SpringJmsMatsFactoryProducer Maven / Gradle / Ivy

Go to download

Mats^3 Spring tooling for the Mats^3 JMS implementation, including an implementation of JmsMatsTransactionManager using Spring's PlatformTransactionManager, and tooling for configuring a MatsFactory for different scenarios: development, staging, production.

The newest version!
package io.mats3.spring.jms.factories;

import java.sql.Connection;

import javax.jms.ConnectionFactory;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import io.mats3.MatsFactory;
import io.mats3.impl.jms.JmsMatsFactory;
import io.mats3.impl.jms.JmsMatsJmsSessionHandler;
import io.mats3.impl.jms.JmsMatsJmsSessionHandler_Pooling;
import io.mats3.impl.jms.JmsMatsTransactionManager;
import io.mats3.impl.jms.JmsMatsTransactionManager_Jms;
import io.mats3.serial.MatsSerializer;
import io.mats3.spring.jms.tx.JmsMatsTransactionManager_JmsAndSpringManagedSqlTx;

/**
 * Provides an easy way to get hold of the most probable {@link JmsMatsFactory} transaction manager configuration in the
 * Spring world (using {@link JmsMatsTransactionManager_JmsAndSpringManagedSqlTx}, or only the
 * {@link JmsMatsTransactionManager_Jms} if no DataSource is needed). You may either supply a {@link DataSource}, or a
 * Spring {@link PlatformTransactionManager} (typically DataSourceTransactionManager or
 * HibernateTransactionManager). The code here is very simple, really just creating the {@link MatsFactory}
 * normally and then wrapping it up in a {@link SpringJmsMatsFactoryWrapper} which provides hook-in to the Spring
 * context (read more about those hook-in features on its {@link SpringJmsMatsFactoryWrapper JavaDoc}).
 * 

* NOTE: It returns an instance of {@link SpringJmsMatsFactoryWrapper}, which it is assumed that you put in the * Spring context as a bean, so that Spring property injection and @PostConstruct is run on it. If you * instead employ a FactoryBean (e.g. because you have made a cool Mats single-annotation-configuration solution for * your multiple codebases), then you need to invoke * {@link SpringJmsMatsFactoryWrapper#postConstructForFactoryBean(Environment, ApplicationContext)} - read up! * * @see SpringJmsMatsFactoryWrapper * @see SpringJmsMatsFactoryWrapper#postConstructForFactoryBean(Environment, ApplicationContext) * * @author Endre Stølsvik 2019-06-10 02:45 - http://stolsvik.com/, [email protected] */ public class SpringJmsMatsFactoryProducer { private static final Logger log = LoggerFactory.getLogger(SpringJmsMatsFactoryProducer.class); private static final String LOG_PREFIX = "#SPRINGJMATS# "; /** * If you need a {@link MatsFactory} employing Spring's DataSourceTransactionManager (which you probably do in a * Spring environment utilizing SQL), this is your factory method. *

* Usage: Make a @Bean-annotated method which returns the result of this method, or employ a Spring * FactoryBean where you then need to invoke * {@link SpringJmsMatsFactoryWrapper#postConstructForFactoryBean(Environment, ApplicationContext)}. * * @param appName * the containing application's name (for debugging purposes, you'll find it in the trace). * @param appVersion * the containing application's version (for debugging purposes, you'll find it in the trace). * @param matsSerializer * the {@link JmsMatsFactory} utilizes the {@link MatsSerializer}, so you need to provide one. (It is * probably the one from the 'mats-serial-json' package). * @param jmsConnectionFactory * the JMS {@link ConnectionFactory} to fetch JMS Connections from, using * {@link ConnectionFactory#createConnection()}. It is assumed that if username and password is needed, * you have configured that on the ConnectionFactory. * @param sqlDataSource * the SQL DataSource which to stash into a Spring {@link DataSourceTransactionManager}, and from which * SQL {@link Connection}s are fetched from, using {@link DataSource#getConnection()}. It is assumed that * if username and password is needed, you have configured that on the DataSource. * @return the produced {@link SpringJmsMatsFactoryWrapper} */ public static SpringJmsMatsFactoryWrapper createSpringDataSourceTxMatsFactory(String appName, String appVersion, MatsSerializer matsSerializer, ConnectionFactory jmsConnectionFactory, DataSource sqlDataSource) { // :: Create the JMS and Spring DataSourceTransactionManager-backed JMS MatsFactory. log.info(LOG_PREFIX + "createSpringDataSourceTxMatsFactory(" + appName + ", " + appVersion + ", " + matsSerializer + ", " + jmsConnectionFactory + ", " + sqlDataSource + ")"); // JMS + Spring's DataSourceTransactionManager-based MatsTransactionManager JmsMatsTransactionManager springSqlTxMgr = JmsMatsTransactionManager_JmsAndSpringManagedSqlTx.create( sqlDataSource); return createJmsMatsFactory(appName, appVersion, matsSerializer, jmsConnectionFactory, springSqlTxMgr); } /** * If you need a {@link MatsFactory} employing a {@link PlatformTransactionManager} of your choosing, which you * quite possibly want in a Spring environment using e.g. Spring JDBC or Hibernate, this is your factory method. *

* Usage: Make a @Bean-annotated method which returns the result of this method, or employ a Spring * FactoryBean where you then need to invoke * {@link SpringJmsMatsFactoryWrapper#postConstructForFactoryBean(Environment, ApplicationContext)}. * * @param appName * the containing application's name (for debugging purposes, you'll find it in the trace). * @param appVersion * the containing application's version (for debugging purposes, you'll find it in the trace). * @param matsSerializer * the {@link JmsMatsFactory} utilizes the {@link MatsSerializer}, so you need to provide one. (It is * probably the one from the 'mats-serial-json' package). * @param jmsConnectionFactory * the JMS {@link ConnectionFactory} to fetch JMS Connections from, using * {@link ConnectionFactory#createConnection()}. It is assumed that if username and password is needed, * you have configured that on the ConnectionFactory. * @param platformTransactionManager * the {@link PlatformTransactionManager} (typically DataSourceTransactionManager or * HibernateTransactionManager) that the MatsFactory should employ. * @return the produced {@link SpringJmsMatsFactoryWrapper} */ public static SpringJmsMatsFactoryWrapper createSpringPlatformTransactionManagerTxMatsFactory( String appName, String appVersion, MatsSerializer matsSerializer, ConnectionFactory jmsConnectionFactory, PlatformTransactionManager platformTransactionManager) { // :: Create the JMS and Spring PlatformTransactionManager-backed JMS MatsFactory. log.info(LOG_PREFIX + "createSpringPlatformTransactionManagerTxMatsFactory(" + appName + ", " + appVersion + ", " + matsSerializer + ", " + jmsConnectionFactory + ", " + platformTransactionManager + ")"); // JMS + Spring's PlatformTransactionManager-based MatsTransactionManager JmsMatsTransactionManager springSqlTxMgr = JmsMatsTransactionManager_JmsAndSpringManagedSqlTx.create( platformTransactionManager); return createJmsMatsFactory(appName, appVersion, matsSerializer, jmsConnectionFactory, springSqlTxMgr); } /** * If you need a {@link MatsFactory} that only handles the JMS transactions, this is your factory method - but if * you DO make any database calls within any Mats endpoint lambda, you will now have no or poor transactional * demarcation, use * {@link #createSpringDataSourceTxMatsFactory(String, String, MatsSerializer, ConnectionFactory, DataSource) * createSpringDataSourceTxMatsFactory(..)} instead. *

* Usage: Make a @Bean-annotated method which returns the result of this method, or employ a Spring * FactoryBean where you then need to invoke * {@link SpringJmsMatsFactoryWrapper#postConstructForFactoryBean(Environment, ApplicationContext)}. * * @param appName * the containing application's name (for debugging purposes, you'll find it in the trace). * @param appVersion * the containing application's version (for debugging purposes, you'll find it in the trace). * @param matsSerializer * the {@link JmsMatsFactory} utilizes the {@link MatsSerializer}, so you need to provide one. (It is * probably the one from the 'mats-serial-json' package). * @param jmsConnectionFactory * the JMS {@link ConnectionFactory} to fetch JMS Connections from, using * {@link ConnectionFactory#createConnection()}. It is assumed that if username and password is needed, * you have configured that on the ConnectionFactory. * @return the produced {@link SpringJmsMatsFactoryWrapper} */ public static SpringJmsMatsFactoryWrapper createJmsTxOnlyMatsFactory(String appName, String appVersion, MatsSerializer matsSerializer, ConnectionFactory jmsConnectionFactory) { // :: Create the JMS and Spring DataSourceTransactionManager-backed JMS MatsFactory. log.info(LOG_PREFIX + "createJmsTxOnlyMatsFactory(" + appName + ", " + appVersion + ", " + matsSerializer + ", " + jmsConnectionFactory + ")"); // JMS only MatsTransactionManager JmsMatsTransactionManager jmsOnlyTxMgr = JmsMatsTransactionManager_Jms.create(); return createJmsMatsFactory(appName, appVersion, matsSerializer, jmsConnectionFactory, jmsOnlyTxMgr); } private static SpringJmsMatsFactoryWrapper createJmsMatsFactory(String appName, String appVersion, MatsSerializer matsSerializer, ConnectionFactory jmsConnectionFactory, JmsMatsTransactionManager txMgr) { // JmsSessionHandler (pooler) JmsMatsJmsSessionHandler jmsSessionHandler = JmsMatsJmsSessionHandler_Pooling.create( jmsConnectionFactory); // The MatsFactory itself, supplying the JmsSessionHandler and MatsTransactionManager. JmsMatsFactory matsFactory = JmsMatsFactory .createMatsFactory(appName, appVersion, jmsSessionHandler, txMgr, matsSerializer); return new SpringJmsMatsFactoryWrapper(jmsConnectionFactory, matsFactory); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy