Refactor method name dispatching to switch statements

Closes gh-25163
This commit is contained in:
Juergen Hoeller
2020-05-29 23:07:25 +02:00
parent 7207f7645c
commit e955e52f2f
15 changed files with 499 additions and 547 deletions

View File

@@ -44,6 +44,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
* A JMS ConnectionFactory adapter that returns the same Connection
@@ -543,124 +544,118 @@ public class SingleConnectionFactory implements ConnectionFactory, QueueConnecti
@Override
@Nullable
public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
if (method.getName().equals("equals") && args != null) {
Object other = args[0];
if (proxy == other) {
return true;
}
if (other == null || !Proxy.isProxyClass(other.getClass())) {
return false;
}
InvocationHandler otherHandler = Proxy.getInvocationHandler(other);
return (otherHandler instanceof SharedConnectionInvocationHandler &&
factory() == ((SharedConnectionInvocationHandler) otherHandler).factory());
}
else if (method.getName().equals("hashCode")) {
// Use hashCode of containing SingleConnectionFactory.
return System.identityHashCode(factory());
}
else if (method.getName().equals("toString")) {
return "Shared JMS Connection: " + getConnection();
}
else if (method.getName().equals("setClientID") && args != null) {
// Handle setClientID method: throw exception if not compatible.
String currentClientId = getConnection().getClientID();
if (currentClientId != null && currentClientId.equals(args[0])) {
return null;
}
else {
throw new javax.jms.IllegalStateException(
"setClientID call not supported on proxy for shared Connection. " +
"Set the 'clientId' property on the SingleConnectionFactory instead.");
}
}
else if (method.getName().equals("setExceptionListener") && args != null) {
// Handle setExceptionListener method: add to the chain.
synchronized (connectionMonitor) {
if (aggregatedExceptionListener != null) {
ExceptionListener listener = (ExceptionListener) args[0];
if (listener != this.localExceptionListener) {
if (this.localExceptionListener != null) {
aggregatedExceptionListener.delegates.remove(this.localExceptionListener);
}
if (listener != null) {
aggregatedExceptionListener.delegates.add(listener);
}
this.localExceptionListener = listener;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "equals":
Object other = args[0];
if (proxy == other) {
return true;
}
if (other == null || !Proxy.isProxyClass(other.getClass())) {
return false;
}
InvocationHandler otherHandler = Proxy.getInvocationHandler(other);
return (otherHandler instanceof SharedConnectionInvocationHandler &&
factory() == ((SharedConnectionInvocationHandler) otherHandler).factory());
case "hashCode":
// Use hashCode of containing SingleConnectionFactory.
return System.identityHashCode(factory());
case "toString":
return "Shared JMS Connection: " + getConnection();
case "setClientID":
// Handle setClientID method: throw exception if not compatible.
String currentClientId = getConnection().getClientID();
if (currentClientId != null && currentClientId.equals(args[0])) {
return null;
}
else {
throw new javax.jms.IllegalStateException(
"setExceptionListener call not supported on proxy for shared Connection. " +
"Set the 'exceptionListener' property on the SingleConnectionFactory instead. " +
"Alternatively, activate SingleConnectionFactory's 'reconnectOnException' feature, " +
"which will allow for registering further ExceptionListeners to the recovery chain.");
"setClientID call not supported on proxy for shared Connection. " +
"Set the 'clientId' property on the SingleConnectionFactory instead.");
}
}
}
else if (method.getName().equals("getExceptionListener")) {
synchronized (connectionMonitor) {
if (this.localExceptionListener != null) {
return this.localExceptionListener;
}
else {
return getExceptionListener();
}
}
}
else if (method.getName().equals("start")) {
localStart();
return null;
}
else if (method.getName().equals("stop")) {
localStop();
return null;
}
else if (method.getName().equals("close")) {
localStop();
synchronized (connectionMonitor) {
if (this.localExceptionListener != null) {
case "setExceptionListener":
// Handle setExceptionListener method: add to the chain.
synchronized (connectionMonitor) {
if (aggregatedExceptionListener != null) {
aggregatedExceptionListener.delegates.remove(this.localExceptionListener);
ExceptionListener listener = (ExceptionListener) args[0];
if (listener != this.localExceptionListener) {
if (this.localExceptionListener != null) {
aggregatedExceptionListener.delegates.remove(this.localExceptionListener);
}
if (listener != null) {
aggregatedExceptionListener.delegates.add(listener);
}
this.localExceptionListener = listener;
}
return null;
}
else {
throw new javax.jms.IllegalStateException(
"setExceptionListener call not supported on proxy for shared Connection. " +
"Set the 'exceptionListener' property on the SingleConnectionFactory instead. " +
"Alternatively, activate SingleConnectionFactory's 'reconnectOnException' feature, " +
"which will allow for registering further ExceptionListeners to the recovery chain.");
}
this.localExceptionListener = null;
}
}
return null;
}
else if (method.getName().equals("createSession") || method.getName().equals("createQueueSession") ||
method.getName().equals("createTopicSession")) {
// Default: JMS 2.0 createSession() method
Integer mode = Session.AUTO_ACKNOWLEDGE;
if (args != null) {
if (args.length == 1) {
// JMS 2.0 createSession(int) method
mode = (Integer) args[0];
}
else if (args.length == 2) {
// JMS 1.1 createSession(boolean, int) method
boolean transacted = (Boolean) args[0];
Integer ackMode = (Integer) args[1];
mode = (transacted ? Session.SESSION_TRANSACTED : ackMode);
}
}
Session session = getSession(getConnection(), mode);
if (session != null) {
if (!method.getReturnType().isInstance(session)) {
String msg = "JMS Session does not implement specific domain: " + session;
try {
session.close();
}
catch (Throwable ex) {
logger.trace("Failed to close newly obtained JMS Session", ex);
}
throw new javax.jms.IllegalStateException(msg);
}
return session;
}
case "getExceptionListener":
synchronized (connectionMonitor) {
if (this.localExceptionListener != null) {
return this.localExceptionListener;
}
else {
return getExceptionListener();
}
}
case "start":
localStart();
return null;
case "stop":
localStop();
return null;
case "close":
localStop();
synchronized (connectionMonitor) {
if (this.localExceptionListener != null) {
if (aggregatedExceptionListener != null) {
aggregatedExceptionListener.delegates.remove(this.localExceptionListener);
}
this.localExceptionListener = null;
}
}
return null;
case "createSession":
case "createQueueSession":
case "createTopicSession":
// Default: JMS 2.0 createSession() method
Integer mode = Session.AUTO_ACKNOWLEDGE;
if (!ObjectUtils.isEmpty(args)) {
if (args.length == 1) {
// JMS 2.0 createSession(int) method
mode = (Integer) args[0];
}
else if (args.length == 2) {
// JMS 1.1 createSession(boolean, int) method
boolean transacted = (Boolean) args[0];
Integer ackMode = (Integer) args[1];
mode = (transacted ? Session.SESSION_TRANSACTED : ackMode);
}
}
Session session = getSession(getConnection(), mode);
if (session != null) {
if (!method.getReturnType().isInstance(session)) {
String msg = "JMS Session does not implement specific domain: " + session;
try {
session.close();
}
catch (Throwable ex) {
logger.trace("Failed to close newly obtained JMS Session", ex);
}
throw new javax.jms.IllegalStateException(msg);
}
return session;
}
}
try {
return method.invoke(getConnection(), args);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 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.
@@ -256,15 +256,16 @@ public class TransactionAwareConnectionFactoryProxy
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Invocation on ConnectionProxy interface coming in...
if (method.getName().equals("equals")) {
// Only consider equal when proxies are identical.
return (proxy == args[0]);
switch (method.getName()) {
case "equals":
// Only consider equal when proxies are identical.
return (proxy == args[0]);
case "hashCode":
// Use hashCode of Connection proxy.
return System.identityHashCode(proxy);
}
else if (method.getName().equals("hashCode")) {
// Use hashCode of Connection proxy.
return System.identityHashCode(proxy);
}
else if (Session.class == method.getReturnType()) {
if (Session.class == method.getReturnType()) {
Session session = ConnectionFactoryUtils.getTransactionalSession(
getTargetConnectionFactory(), this.target, isSynchedLocalTransactionAllowed());
if (session != null) {
@@ -328,27 +329,23 @@ public class TransactionAwareConnectionFactoryProxy
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Invocation on SessionProxy interface coming in...
if (method.getName().equals("equals")) {
// Only consider equal when proxies are identical.
return (proxy == args[0]);
}
else if (method.getName().equals("hashCode")) {
// Use hashCode of Connection proxy.
return System.identityHashCode(proxy);
}
else if (method.getName().equals("commit")) {
throw new TransactionInProgressException("Commit call not allowed within a managed transaction");
}
else if (method.getName().equals("rollback")) {
throw new TransactionInProgressException("Rollback call not allowed within a managed transaction");
}
else if (method.getName().equals("close")) {
// Handle close method: not to be closed within a transaction.
return null;
}
else if (method.getName().equals("getTargetSession")) {
// Handle getTargetSession method: return underlying Session.
return this.target;
switch (method.getName()) {
case "equals":
// Only consider equal when proxies are identical.
return (proxy == args[0]);
case "hashCode":
// Use hashCode of Connection proxy.
return System.identityHashCode(proxy);
case "commit":
throw new TransactionInProgressException("Commit call not allowed within a managed transaction");
case "rollback":
throw new TransactionInProgressException("Rollback call not allowed within a managed transaction");
case "close":
// Handle close method: not to be closed within a transaction.
return null;
case "getTargetSession":
// Handle getTargetSession method: return underlying Session.
return this.target;
}
// Invoke method on target Session.