diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java
index 7e6db639550e0bfbab98127d30d646d2e2f74200..9ca006be4285b2654d9bd1b6294b764d5eb4dce2 100644
--- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java
+++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,8 +31,8 @@ import org.springframework.util.Assert;
* Generic auto proxy creator that builds AOP proxies for specific beans
* based on detected Advisors for each bean.
*
- *
Subclasses must implement the abstract {@link #findCandidateAdvisors()}
- * method to return a list of Advisors applying to any object. Subclasses can
+ *
Subclasses may override the {@link #findCandidateAdvisors()} method to
+ * return a custom list of Advisors applying to any object. Subclasses can
* also override the inherited {@link #shouldSkip} method to exclude certain
* objects from auto-proxying.
*
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java
index b77b31700add0e9e58b8526ae7fdc7962d49ef6a..dce36a05e42df8f1464429d500a8fcec73165376 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/BeansDtdResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
/**
- * EntityResolver implementation for the Spring beans DTD,
+ * {@link EntityResolver} implementation for the Spring beans DTD,
* to load the DTD from the Spring class path (or JAR file).
*
*
Fetches "spring-beans.dtd" from the class path resource
@@ -57,6 +57,7 @@ public class BeansDtdResolver implements EntityResolver {
logger.trace("Trying to resolve XML entity with public ID [" + publicId +
"] and system ID [" + systemId + "]");
}
+
if (systemId != null && systemId.endsWith(DTD_EXTENSION)) {
int lastPathSeparator = systemId.lastIndexOf('/');
int dtdNameStart = systemId.indexOf(DTD_NAME, lastPathSeparator);
@@ -83,7 +84,7 @@ public class BeansDtdResolver implements EntityResolver {
}
}
- // Use the default behavior -> download from website or wherever.
+ // Fall back to the parser's default behavior.
return null;
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java
index 96ac31fda4d9fb4a4d60b7ab28a9473a06166bc1..696a8498010101510c80e1b4bb41a4400021ee62 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,15 +38,15 @@ import org.springframework.util.CollectionUtils;
* {@link EntityResolver} implementation that attempts to resolve schema URLs into
* local {@link ClassPathResource classpath resources} using a set of mappings files.
*
- *
By default, this class will look for mapping files in the classpath using the pattern:
- * {@code META-INF/spring.schemas} allowing for multiple files to exist on the
- * classpath at any one time.
+ *
By default, this class will look for mapping files in the classpath using the
+ * pattern: {@code META-INF/spring.schemas} allowing for multiple files to exist on
+ * the classpath at any one time.
*
- * The format of {@code META-INF/spring.schemas} is a properties
- * file where each line should be of the form {@code systemId=schema-location}
- * where {@code schema-location} should also be a schema file in the classpath.
- * Since systemId is commonly a URL, one must be careful to escape any ':' characters
- * which are treated as delimiters in properties files.
+ *
The format of {@code META-INF/spring.schemas} is a properties file where each line
+ * should be of the form {@code systemId=schema-location} where {@code schema-location}
+ * should also be a schema file in the classpath. Since systemId is commonly a URL,
+ * one must be careful to escape any ':' characters which are treated as delimiters
+ * in properties files.
*
*
The pattern for the mapping files can be overidden using the
* {@link #PluggableSchemaResolver(ClassLoader, String)} constructor
@@ -103,6 +103,7 @@ public class PluggableSchemaResolver implements EntityResolver {
this.schemaMappingsLocation = schemaMappingsLocation;
}
+
@Override
@Nullable
public InputSource resolveEntity(String publicId, @Nullable String systemId) throws IOException {
@@ -131,6 +132,8 @@ public class PluggableSchemaResolver implements EntityResolver {
}
}
}
+
+ // Fall back to the parser's default behavior.
return null;
}
@@ -169,7 +172,7 @@ public class PluggableSchemaResolver implements EntityResolver {
@Override
public String toString() {
- return "EntityResolver using mappings " + getSchemaMappings();
+ return "EntityResolver using schema mappings " + getSchemaMappings();
}
}
diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java b/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java
index 5388a6afa0746aaece00622d9d508bc2b91ecc92..4d0d3a1d2e93f6e154540e243d59fffddc89526f 100644
--- a/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java
+++ b/spring-jms/src/main/java/org/springframework/jms/connection/JmsResourceHolder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ package org.springframework.jms.connection;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
@@ -58,11 +57,11 @@ public class JmsResourceHolder extends ResourceHolderSupport {
private boolean frozen = false;
- private final List connections = new LinkedList<>();
+ private final LinkedList connections = new LinkedList<>();
- private final List sessions = new LinkedList<>();
+ private final LinkedList sessions = new LinkedList<>();
- private final Map> sessionsPerConnection = new HashMap<>();
+ private final Map> sessionsPerConnection = new HashMap<>();
/**
@@ -117,10 +116,19 @@ public class JmsResourceHolder extends ResourceHolderSupport {
}
+ /**
+ * Return whether this resource holder is frozen, i.e. does not
+ * allow for adding further Connections and Sessions to it.
+ * @see #addConnection
+ * @see #addSession
+ */
public final boolean isFrozen() {
return this.frozen;
}
+ /**
+ * Add the given Connection to this resource holder.
+ */
public final void addConnection(Connection connection) {
Assert.isTrue(!this.frozen, "Cannot add Connection because JmsResourceHolder is frozen");
Assert.notNull(connection, "Connection must not be null");
@@ -129,54 +137,102 @@ public class JmsResourceHolder extends ResourceHolderSupport {
}
}
+ /**
+ * Add the given Session to this resource holder.
+ */
public final void addSession(Session session) {
addSession(session, null);
}
+ /**
+ * Add the given Session to this resource holder,
+ * registered for a specific Connection.
+ */
public final void addSession(Session session, @Nullable Connection connection) {
Assert.isTrue(!this.frozen, "Cannot add Session because JmsResourceHolder is frozen");
Assert.notNull(session, "Session must not be null");
if (!this.sessions.contains(session)) {
this.sessions.add(session);
if (connection != null) {
- List sessions = this.sessionsPerConnection.computeIfAbsent(connection, k -> new LinkedList<>());
+ LinkedList sessions =
+ this.sessionsPerConnection.computeIfAbsent(connection, k -> new LinkedList<>());
sessions.add(session);
}
}
}
+ /**
+ * Determine whether the given Session is registered
+ * with this resource holder.
+ */
public boolean containsSession(Session session) {
return this.sessions.contains(session);
}
+ /**
+ * Return this resource holder's default Connection,
+ * or {@code null} if none.
+ */
@Nullable
public Connection getConnection() {
- return (!this.connections.isEmpty() ? this.connections.get(0) : null);
+ return this.connections.peek();
}
+ /**
+ * Return this resource holder's Connection of the given type,
+ * or {@code null} if none.
+ */
@Nullable
- public Connection getConnection(Class extends Connection> connectionType) {
+ public C getConnection(Class connectionType) {
return CollectionUtils.findValueOfType(this.connections, connectionType);
}
+ /**
+ * Return an existing original Session, if any.
+ * In contrast to {@link #getSession()}, this must not lazily initialize
+ * a new Session, not even in {@link JmsResourceHolder} subclasses.
+ */
+ @Nullable
+ Session getOriginalSession() {
+ return this.sessions.peek();
+ }
+
+ /**
+ * Return this resource holder's default Session,
+ * or {@code null} if none.
+ */
@Nullable
public Session getSession() {
- return (!this.sessions.isEmpty() ? this.sessions.get(0) : null);
+ return this.sessions.peek();
}
+ /**
+ * Return this resource holder's Session of the given type,
+ * or {@code null} if none.
+ */
@Nullable
- public Session getSession(Class extends Session> sessionType) {
+ public S getSession(Class sessionType) {
return getSession(sessionType, null);
}
+ /**
+ * Return this resource holder's Session of the given type
+ * for the given connection, or {@code null} if none.
+ */
@Nullable
- public Session getSession(Class extends Session> sessionType, @Nullable Connection connection) {
- List sessions = (connection != null ? this.sessionsPerConnection.get(connection) : this.sessions);
+ public S getSession(Class sessionType, @Nullable Connection connection) {
+ LinkedList sessions =
+ (connection != null ? this.sessionsPerConnection.get(connection) : this.sessions);
return CollectionUtils.findValueOfType(sessions, sessionType);
}
+ /**
+ * Commit all of this resource holder's Sessions.
+ * @throws JMSException if thrown from a Session commit attempt
+ * @see Session#commit()
+ */
public void commitAll() throws JMSException {
for (Session session : this.sessions) {
try {
@@ -218,6 +274,10 @@ public class JmsResourceHolder extends ResourceHolderSupport {
}
}
+ /**
+ * Close all of this resource holder's Sessions and clear its state.
+ * @see Session#close()
+ */
public void closeAll() {
for (Session session : this.sessions) {
try {
diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java b/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java
index 41dd20f056caeb0e79f5e9fac5b948b2b951d2ef..d23a1ac01eac4cd1061945b141efc13d38beccc9 100644
--- a/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java
+++ b/spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -96,6 +96,8 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
@Nullable
private ConnectionFactory connectionFactory;
+ private boolean lazyResourceRetrieval = false;
+
/**
* Create a new JmsTransactionManager for bean-style usage.
@@ -128,7 +130,7 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
* Set the JMS ConnectionFactory that this instance should manage transactions for.
*/
public void setConnectionFactory(@Nullable ConnectionFactory cf) {
- if (cf != null && cf instanceof TransactionAwareConnectionFactoryProxy) {
+ if (cf instanceof TransactionAwareConnectionFactoryProxy) {
// If we got a TransactionAwareConnectionFactoryProxy, we need to perform transactions
// for its underlying target ConnectionFactory, else JMS access code won't see
// properly exposed transactions (i.e. transactions for the target ConnectionFactory).
@@ -159,6 +161,19 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
return connectionFactory;
}
+ /**
+ * Specify whether this transaction manager should lazily retrieve a JMS
+ * Connection and Session on access within a transaction ({@code true}).
+ * By default, it will eagerly create a JMS Connection and Session at
+ * transaction begin ({@code false}).
+ * @since 5.1.6
+ * @see JmsResourceHolder#getConnection()
+ * @see JmsResourceHolder#getSession()
+ */
+ public void setLazyResourceRetrieval(boolean lazyResourceRetrieval) {
+ this.lazyResourceRetrieval = lazyResourceRetrieval;
+ }
+
/**
* Make sure the ConnectionFactory has been set.
*/
@@ -200,12 +215,18 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
Connection con = null;
Session session = null;
try {
- con = createConnection();
- session = createSession(con);
- if (logger.isDebugEnabled()) {
- logger.debug("Created JMS transaction on Session [" + session + "] from Connection [" + con + "]");
+ JmsResourceHolder resourceHolder;
+ if (this.lazyResourceRetrieval) {
+ resourceHolder = new LazyJmsResourceHolder(connectionFactory);
+ }
+ else {
+ con = createConnection();
+ session = createSession(con);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Created JMS transaction on Session [" + session + "] from Connection [" + con + "]");
+ }
+ resourceHolder = new JmsResourceHolder(connectionFactory, con, session);
}
- JmsResourceHolder resourceHolder = new JmsResourceHolder(connectionFactory, con, session);
resourceHolder.setSynchronizedWithTransaction(true);
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
@@ -250,7 +271,7 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
@Override
protected void doCommit(DefaultTransactionStatus status) {
JmsTransactionObject txObject = (JmsTransactionObject) status.getTransaction();
- Session session = txObject.getResourceHolder().getSession();
+ Session session = txObject.getResourceHolder().getOriginalSession();
if (session != null) {
try {
if (status.isDebug()) {
@@ -270,7 +291,7 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
@Override
protected void doRollback(DefaultTransactionStatus status) {
JmsTransactionObject txObject = (JmsTransactionObject) status.getTransaction();
- Session session = txObject.getResourceHolder().getSession();
+ Session session = txObject.getResourceHolder().getOriginalSession();
if (session != null) {
try {
if (status.isDebug()) {
@@ -321,6 +342,85 @@ public class JmsTransactionManager extends AbstractPlatformTransactionManager
}
+ /**
+ * Lazily initializing variant of {@link JmsResourceHolder},
+ * initializing a JMS Connection and Session on user access.
+ */
+ private class LazyJmsResourceHolder extends JmsResourceHolder {
+
+ private boolean connectionInitialized = false;
+
+ private boolean sessionInitialized = false;
+
+ public LazyJmsResourceHolder(@Nullable ConnectionFactory connectionFactory) {
+ super(connectionFactory);
+ }
+
+ @Override
+ @Nullable
+ public Connection getConnection() {
+ initializeConnection();
+ return super.getConnection();
+ }
+
+ @Override
+ @Nullable
+ public C getConnection(Class connectionType) {
+ initializeConnection();
+ return super.getConnection(connectionType);
+ }
+
+ @Override
+ @Nullable
+ public Session getSession() {
+ initializeSession();
+ return super.getSession();
+ }
+
+ @Override
+ @Nullable
+ public S getSession(Class sessionType) {
+ initializeSession();
+ return super.getSession(sessionType);
+ }
+
+ @Override
+ @Nullable
+ public S getSession(Class sessionType, @Nullable Connection connection) {
+ initializeSession();
+ return super.getSession(sessionType, connection);
+ }
+
+ private void initializeConnection() {
+ if (!this.connectionInitialized) {
+ try {
+ addConnection(createConnection());
+ }
+ catch (JMSException ex) {
+ throw new CannotCreateTransactionException(
+ "Failed to lazily initialize JMS Connection for transaction", ex);
+ }
+ this.connectionInitialized = true;
+ }
+ }
+
+ private void initializeSession() {
+ if (!this.sessionInitialized) {
+ Connection con = getConnection();
+ Assert.state(con != null, "No transactional JMS Connection");
+ try {
+ addSession(createSession(con), con);
+ }
+ catch (JMSException ex) {
+ throw new CannotCreateTransactionException(
+ "Failed to lazily initialize JMS Session for transaction", ex);
+ }
+ this.sessionInitialized = true;
+ }
+ }
+ }
+
+
/**
* JMS transaction object, representing a JmsResourceHolder.
* Used as transaction object by JmsTransactionManager.
diff --git a/spring-jms/src/test/java/org/springframework/jms/connection/JmsTransactionManagerTests.java b/spring-jms/src/test/java/org/springframework/jms/connection/JmsTransactionManagerTests.java
index bd0fb1bd97aae9d75772c5bb4ceb3ad7a99d260a..1019100b1a7655ee0064d66fb5c0e19558ce38eb 100644
--- a/spring-jms/src/test/java/org/springframework/jms/connection/JmsTransactionManagerTests.java
+++ b/spring-jms/src/test/java/org/springframework/jms/connection/JmsTransactionManagerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,6 @@ import org.junit.Test;
import org.springframework.jms.StubQueue;
import org.springframework.jms.core.JmsTemplate;
-import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.SessionCallback;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
@@ -67,12 +66,9 @@ public class JmsTransactionManagerTests {
JmsTransactionManager tm = new JmsTransactionManager(cf);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
JmsTemplate jt = new JmsTemplate(cf);
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
tm.commit(ts);
@@ -93,12 +89,9 @@ public class JmsTransactionManagerTests {
JmsTransactionManager tm = new JmsTransactionManager(cf);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
JmsTemplate jt = new JmsTemplate(cf);
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
tm.rollback(ts);
@@ -119,23 +112,17 @@ public class JmsTransactionManagerTests {
JmsTransactionManager tm = new JmsTransactionManager(cf);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
final JmsTemplate jt = new JmsTemplate(cf);
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
TransactionTemplate tt = new TransactionTemplate(tm);
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
}
});
@@ -158,23 +145,17 @@ public class JmsTransactionManagerTests {
JmsTransactionManager tm = new JmsTransactionManager(cf);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
final JmsTemplate jt = new JmsTemplate(cf);
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
TransactionTemplate tt = new TransactionTemplate(tm);
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
status.setRollbackOnly();
}
@@ -206,33 +187,24 @@ public class JmsTransactionManagerTests {
JmsTransactionManager tm = new JmsTransactionManager(cf);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
final JmsTemplate jt = new JmsTemplate(cf);
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
TransactionTemplate tt = new TransactionTemplate(tm);
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess != session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertNotSame(sess, session);
+ return null;
});
}
});
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
tm.commit(ts);
@@ -255,33 +227,24 @@ public class JmsTransactionManagerTests {
JmsTransactionManager tm = new JmsTransactionManager(cf);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
final JmsTemplate jt = new JmsTemplate(cf);
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
TransactionTemplate tt = new TransactionTemplate(tm);
tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
tt.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess != session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertNotSame(sess, session);
+ return null;
});
}
});
- jt.execute(new SessionCallback() {
- @Override
- public Void doInJms(Session sess) {
- assertTrue(sess == session);
- return null;
- }
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
});
tm.commit(ts);
@@ -310,12 +273,7 @@ public class JmsTransactionManagerTests {
JmsTransactionManager tm = new JmsTransactionManager(cf);
TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
JmsTemplate jt = new JmsTemplate(cf);
- jt.send(dest, new MessageCreator() {
- @Override
- public Message createMessage(Session session) throws JMSException {
- return message;
- }
- });
+ jt.send(dest, sess -> message);
tm.commit(ts);
verify(producer).send(message);
@@ -325,4 +283,39 @@ public class JmsTransactionManagerTests {
verify(con).close();
}
+ @Test
+ public void testLazyTransactionalSession() throws JMSException {
+ ConnectionFactory cf = mock(ConnectionFactory.class);
+ Connection con = mock(Connection.class);
+ final Session session = mock(Session.class);
+
+ JmsTransactionManager tm = new JmsTransactionManager(cf);
+ tm.setLazyResourceRetrieval(true);
+ TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
+
+ given(cf.createConnection()).willReturn(con);
+ given(con.createSession(true, Session.AUTO_ACKNOWLEDGE)).willReturn(session);
+
+ JmsTemplate jt = new JmsTemplate(cf);
+ jt.execute((SessionCallback) sess -> {
+ assertSame(sess, session);
+ return null;
+ });
+ tm.commit(ts);
+
+ verify(session).commit();
+ verify(session).close();
+ verify(con).close();
+ }
+
+ @Test
+ public void testLazyWithoutSessionAccess() {
+ ConnectionFactory cf = mock(ConnectionFactory.class);
+
+ JmsTransactionManager tm = new JmsTransactionManager(cf);
+ tm.setLazyResourceRetrieval(true);
+ TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
+ tm.commit(ts);
+ }
+
}