Spring Transaction module providing comprehensive transaction management infrastructure for imperative and reactive applications
Java Connector Architecture (JCA) support for integrating with resource adapters and message endpoints in enterprise application servers.
Spring's JCA support is provided through two main packages:
Base class for message endpoint factories that integrate with JCA-compliant resource adapters.
/**
* Abstract base class for JCA 1.7 MessageEndpointFactory implementations.
* Provides transaction management integration.
*/
public abstract class AbstractMessageEndpointFactory
implements MessageEndpointFactory, BeanNameAware {
/**
* Set the transaction manager to use for transactional endpoints.
* Accepts either TransactionManager or TransactionFactory.
*/
public void setTransactionManager(Object transactionManager);
/**
* Set the JCA TransactionFactory to use for transactional endpoints.
*/
public void setTransactionFactory(TransactionFactory transactionFactory);
/**
* Set the name for transactions created by this endpoint.
*/
public void setTransactionName(String transactionName);
/**
* Set the transaction timeout in seconds.
*/
public void setTransactionTimeout(int transactionTimeout);
/**
* Set the bean name for this endpoint factory.
*/
@Override
public void setBeanName(String beanName);
/**
* Return the activation name for this endpoint.
*/
public String getActivationName();
/**
* Return the endpoint class handled by this factory.
*/
protected abstract Class<?> getEndpointClass();
/**
* Create the actual endpoint instance.
*/
protected abstract AbstractMessageEndpoint createEndpointInternal() throws UnavailableException;
@Override
public MessageEndpoint createEndpoint(XAResource xaResource) throws UnavailableException;
@Override
public MessageEndpoint createEndpoint(XAResource xaResource, long timeout)
throws UnavailableException;
@Override
public boolean isDeliveryTransacted(Method method) throws NoSuchMethodException;
}Concrete MessageEndpointFactory implementation that wraps a plain message listener object.
/**
* Generic JCA 1.7 MessageEndpointFactory implementation that wraps
* a plain message listener object.
*/
public class GenericMessageEndpointFactory extends AbstractMessageEndpointFactory {
/**
* Set the message listener object to expose as endpoint.
*/
public void setMessageListener(Object messageListener);
/**
* Return the configured message listener object.
*/
protected Object getMessageListener();
@Override
public MessageEndpoint createEndpoint(XAResource xaResource) throws UnavailableException;
@Override
protected AbstractMessageEndpoint createEndpointInternal() throws UnavailableException;
}Usage Example:
@Configuration
public class JcaConfig {
@Bean
public GenericMessageEndpointFactory messageEndpointFactory(
MyMessageListener listener,
JtaTransactionManager transactionManager) {
GenericMessageEndpointFactory factory = new GenericMessageEndpointFactory();
factory.setMessageListener(listener);
factory.setTransactionManager(transactionManager);
factory.setTransactionName("MessageEndpointTransaction");
factory.setTransactionTimeout(30);
return factory;
}
}Manager that activates a JCA message endpoint using a given MessageEndpointFactory and ResourceAdapter.
/**
* Generic manager for JCA 1.7 message endpoints, activating a specific
* message endpoint with a ResourceAdapter.
*/
public class GenericMessageEndpointManager
implements SmartLifecycle, InitializingBean, DisposableBean {
/**
* Set the JCA ResourceAdapter to use for activation.
*/
public void setResourceAdapter(ResourceAdapter resourceAdapter);
/**
* Return the configured ResourceAdapter.
*/
public ResourceAdapter getResourceAdapter();
/**
* Set the MessageEndpointFactory to activate.
*/
public void setMessageEndpointFactory(MessageEndpointFactory messageEndpointFactory);
/**
* Return the configured MessageEndpointFactory.
*/
public MessageEndpointFactory getMessageEndpointFactory();
/**
* Set the JCA ActivationSpec to use for activation.
*/
public void setActivationSpec(ActivationSpec activationSpec);
/**
* Return the configured ActivationSpec.
*/
public ActivationSpec getActivationSpec();
/**
* Set whether to automatically start the endpoint on context refresh.
* Default is true.
*/
public void setAutoStartup(boolean autoStartup);
@Override
public boolean isAutoStartup();
/**
* Set the startup phase for this lifecycle bean.
*/
public void setPhase(int phase);
@Override
public int getPhase();
@Override
public void afterPropertiesSet() throws ResourceException;
@Override
public void start();
@Override
public void stop();
@Override
public void stop(Runnable callback);
@Override
public boolean isRunning();
@Override
public void destroy();
}Usage Example:
@Configuration
public class MessageEndpointConfig {
@Bean
public GenericMessageEndpointManager endpointManager(
ResourceAdapter resourceAdapter,
GenericMessageEndpointFactory endpointFactory,
ActivationSpec activationSpec) {
GenericMessageEndpointManager manager = new GenericMessageEndpointManager();
manager.setResourceAdapter(resourceAdapter);
manager.setMessageEndpointFactory(endpointFactory);
manager.setActivationSpec(activationSpec);
manager.setAutoStartup(true);
return manager;
}
}FactoryBean that creates a local JCA connection factory for use in standalone applications.
/**
* FactoryBean that creates a local JCA connection factory in standalone mode,
* without support for XA transactions.
*/
public class LocalConnectionFactoryBean
implements FactoryBean<Object>, InitializingBean {
/**
* Set the JCA ManagedConnectionFactory to use.
*/
public void setManagedConnectionFactory(ManagedConnectionFactory managedConnectionFactory);
/**
* Set the JCA ConnectionManager to use.
* If not specified, a default ConnectionManager will be created.
*/
public void setConnectionManager(ConnectionManager connectionManager);
@Override
public void afterPropertiesSet() throws ResourceException;
@Override
public Object getObject();
@Override
public Class<?> getObjectType();
@Override
public boolean isSingleton();
}Usage Example:
@Configuration
public class ConnectionConfig {
@Bean
public LocalConnectionFactoryBean connectionFactory(
ManagedConnectionFactory managedConnectionFactory) {
LocalConnectionFactoryBean factory = new LocalConnectionFactoryBean();
factory.setManagedConnectionFactory(managedConnectionFactory);
return factory;
}
@Bean
public DataSource dataSource(Object connectionFactory) throws Exception {
// Use the connection factory
return (DataSource) connectionFactory;
}
}FactoryBean that bootstraps and exposes a JCA ResourceAdapter in standalone mode.
/**
* FactoryBean that bootstraps a JCA ResourceAdapter in standalone mode,
* starting and stopping it as part of the application lifecycle.
*/
public class ResourceAdapterFactoryBean
implements FactoryBean<ResourceAdapter>, InitializingBean, DisposableBean {
/**
* Set the ResourceAdapter class to instantiate.
*/
public void setResourceAdapterClass(Class<? extends ResourceAdapter> resourceAdapterClass);
/**
* Set the ResourceAdapter instance directly.
*/
public void setResourceAdapter(ResourceAdapter resourceAdapter);
/**
* Set the JCA BootstrapContext to use for starting the ResourceAdapter.
*/
public void setBootstrapContext(BootstrapContext bootstrapContext);
/**
* Set the JCA WorkManager to include in the BootstrapContext.
*/
public void setWorkManager(WorkManager workManager);
/**
* Set the JCA XATerminator to include in the BootstrapContext.
*/
public void setXaTerminator(XATerminator xaTerminator);
@Override
public void afterPropertiesSet() throws ResourceException;
@Override
public ResourceAdapter getObject();
@Override
public Class<? extends ResourceAdapter> getObjectType();
@Override
public boolean isSingleton();
@Override
public void destroy();
}Usage Example:
@Configuration
public class ResourceAdapterConfig {
@Bean
public ResourceAdapterFactoryBean resourceAdapter(
WorkManager workManager,
XATerminator xaTerminator) {
ResourceAdapterFactoryBean factory = new ResourceAdapterFactoryBean();
factory.setResourceAdapterClass(MyResourceAdapter.class);
factory.setWorkManager(workManager);
factory.setXaTerminator(xaTerminator);
return factory;
}
}Simple implementation of JCA BootstrapContext interface for standalone usage.
/**
* Simple implementation of the JCA 1.7 BootstrapContext interface,
* for use in standalone applications.
*/
public class SimpleBootstrapContext implements BootstrapContext {
/**
* Create a new SimpleBootstrapContext for the given WorkManager.
*/
public SimpleBootstrapContext(WorkManager workManager);
/**
* Create a new SimpleBootstrapContext for the given WorkManager and XATerminator.
*/
public SimpleBootstrapContext(WorkManager workManager, XATerminator xaTerminator);
/**
* Create a new SimpleBootstrapContext with WorkManager, XATerminator,
* and TransactionSynchronizationRegistry.
*/
public SimpleBootstrapContext(
WorkManager workManager,
XATerminator xaTerminator,
TransactionSynchronizationRegistry transactionSynchronizationRegistry);
@Override
public WorkManager getWorkManager();
@Override
public XATerminator getXATerminator();
@Override
public Timer createTimer() throws UnavailableException;
@Override
public boolean isContextSupported(Class<? extends WorkContext> workContextClass);
@Override
public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry();
}Usage Example:
@Configuration
public class BootstrapContextConfig {
@Bean
public SimpleBootstrapContext bootstrapContext(
WorkManager workManager,
XATerminator xaTerminator,
TransactionSynchronizationRegistry txSyncRegistry) {
return new SimpleBootstrapContext(
workManager,
xaTerminator,
txSyncRegistry
);
}
@Bean
public ResourceAdapterFactoryBean resourceAdapter(SimpleBootstrapContext bootstrapContext) {
ResourceAdapterFactoryBean factory = new ResourceAdapterFactoryBean();
factory.setResourceAdapterClass(MyResourceAdapter.class);
factory.setBootstrapContext(bootstrapContext);
return factory;
}
}@Configuration
public class CompleteJcaConfig {
@Bean
public SimpleBootstrapContext bootstrapContext() {
// Create work manager and XA terminator
WorkManager workManager = new SimpleWorkManager();
XATerminator xaTerminator = new SimpleXATerminator();
return new SimpleBootstrapContext(workManager, xaTerminator);
}
@Bean
public ResourceAdapterFactoryBean resourceAdapter(SimpleBootstrapContext bootstrapContext) {
ResourceAdapterFactoryBean factory = new ResourceAdapterFactoryBean();
factory.setResourceAdapterClass(MyResourceAdapter.class);
factory.setBootstrapContext(bootstrapContext);
return factory;
}
@Bean
public GenericMessageEndpointFactory endpointFactory(
MyMessageListener listener,
JtaTransactionManager transactionManager) {
GenericMessageEndpointFactory factory = new GenericMessageEndpointFactory();
factory.setMessageListener(listener);
factory.setTransactionManager(transactionManager);
return factory;
}
@Bean
public GenericMessageEndpointManager endpointManager(
ResourceAdapter resourceAdapter,
GenericMessageEndpointFactory endpointFactory,
ActivationSpec activationSpec) {
GenericMessageEndpointManager manager = new GenericMessageEndpointManager();
manager.setResourceAdapter(resourceAdapter);
manager.setMessageEndpointFactory(endpointFactory);
manager.setActivationSpec(activationSpec);
return manager;
}
}@Configuration
public class StandaloneJcaConfig {
@Bean
public ManagedConnectionFactory managedConnectionFactory() {
MyManagedConnectionFactory mcf = new MyManagedConnectionFactory();
mcf.setServerName("localhost");
mcf.setPortNumber(5432);
return mcf;
}
@Bean
public LocalConnectionFactoryBean connectionFactory(
ManagedConnectionFactory managedConnectionFactory) {
LocalConnectionFactoryBean factory = new LocalConnectionFactoryBean();
factory.setManagedConnectionFactory(managedConnectionFactory);
return factory;
}
@Bean
public DataSource dataSource() throws Exception {
return (DataSource) connectionFactory(managedConnectionFactory()).getObject();
}
}public class MyMessageListener implements MessageListener {
@Override
public void onMessage(Message message) {
// Process message
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
try {
String text = textMessage.getText();
processMessage(text);
} catch (JMSException e) {
throw new RuntimeException("Failed to process message", e);
}
}
}
private void processMessage(String message) {
// Business logic
}
}
@Configuration
public class ListenerConfig {
@Bean
public MyMessageListener messageListener() {
return new MyMessageListener();
}
@Bean
public GenericMessageEndpointFactory endpointFactory(
MyMessageListener listener,
JtaTransactionManager transactionManager) {
GenericMessageEndpointFactory factory = new GenericMessageEndpointFactory();
factory.setMessageListener(listener);
factory.setTransactionManager(transactionManager);
factory.setTransactionName("MessageProcessing");
return factory;
}
}AbstractMessageEndpointFactory provides transaction management for message endpointsGenericMessageEndpointFactory wraps any message listener object as a JCA message endpointGenericMessageEndpointManager handles the lifecycle of message endpoint activation with a resource adapterLocalConnectionFactoryBean creates non-XA connection factories for standalone useResourceAdapterFactoryBean manages ResourceAdapter lifecycle including bootstrap and shutdownSimpleBootstrapContext provides basic JCA infrastructure for standalone applicationssetAutoStartup(false) on GenericMessageEndpointManager to control endpoint activation manuallysetTransactionTimeout()Install with Tessl CLI
npx tessl i tessl/maven-org-springframework--spring-tx