diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessor.java
index e9ba8b46f85..c4e21122ed8 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessor.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessor.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.
@@ -54,8 +54,9 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* will be short-circuited. The only further processing applied is the
* {@link #postProcessAfterInitialization} callback from the configured
* {@link BeanPostProcessor BeanPostProcessors}.
- *
This callback will only be applied to bean definitions with a bean class.
- * In particular, it will not be applied to beans with a factory method.
+ *
This callback will be applied to bean definitions with their bean class,
+ * as well as to factory-method definitions in which case the returned bean type
+ * will be passed in here.
*
Post-processors may implement the extended
* {@link SmartInstantiationAwareBeanPostProcessor} interface in order
* to predict the type of the bean object that they are going to return here.
@@ -66,7 +67,8 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
* or {@code null} to proceed with default instantiation
* @throws org.springframework.beans.BeansException in case of errors
* @see #postProcessAfterInstantiation
- * @see org.springframework.beans.factory.support.AbstractBeanDefinition#hasBeanClass
+ * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getBeanClass()
+ * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName()
*/
@Nullable
default Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
index fd73df34499..12cd2836a7c 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
@@ -140,68 +140,68 @@ public abstract class Operator extends SpelNodeImpl {
// This code block checks whether the left or right operand is null and handles
// those cases before letting the original code (that only handled actual numbers) run
Label rightIsNonNull = new Label();
- mv.visitInsn(DUP); // stack: left/right/right
- mv.visitJumpInsn(IFNONNULL, rightIsNonNull); // stack: left/right
+ mv.visitInsn(DUP); // stack: left/right/right
+ mv.visitJumpInsn(IFNONNULL, rightIsNonNull); // stack: left/right
// here: RIGHT==null LEFT==unknown
- mv.visitInsn(SWAP); // right/left
+ mv.visitInsn(SWAP); // right/left
Label leftNotNullRightIsNull = new Label();
- mv.visitJumpInsn(IFNONNULL, leftNotNullRightIsNull); // stack: right
+ mv.visitJumpInsn(IFNONNULL, leftNotNullRightIsNull); // stack: right
// here: RIGHT==null LEFT==null
- mv.visitInsn(POP); // stack:
+ mv.visitInsn(POP); // stack:
// load 0 or 1 depending on comparison instruction
switch (compInstruction1) {
case IFGE: // OpLT
case IFLE: // OpGT
- mv.visitInsn(ICONST_0); // false - null is not < or > null
+ mv.visitInsn(ICONST_0); // false - null is not < or > null
break;
case IFGT: // OpLE
case IFLT: // OpGE
- mv.visitInsn(ICONST_1); // true - null is <= or >= null
+ mv.visitInsn(ICONST_1); // true - null is <= or >= null
break;
default:
- throw new IllegalStateException("Unsupported: "+compInstruction1);
+ throw new IllegalStateException("Unsupported: " + compInstruction1);
}
mv.visitJumpInsn(GOTO, endOfIf);
- mv.visitLabel(leftNotNullRightIsNull); // stack: right
+ mv.visitLabel(leftNotNullRightIsNull); // stack: right
// RIGHT==null LEFT!=null
- mv.visitInsn(POP); // stack:
+ mv.visitInsn(POP); // stack:
// load 0 or 1 depending on comparison instruction
switch (compInstruction1) {
case IFGE: // OpLT
case IFGT: // OpLE
- mv.visitInsn(ICONST_0); // false - something is not < or <= null
+ mv.visitInsn(ICONST_0); // false - something is not < or <= null
break;
case IFLE: // OpGT
case IFLT: // OpGE
- mv.visitInsn(ICONST_1); // true - something is > or >= null
+ mv.visitInsn(ICONST_1); // true - something is > or >= null
break;
default:
- throw new IllegalStateException("Unsupported: "+compInstruction1);
+ throw new IllegalStateException("Unsupported: " + compInstruction1);
}
mv.visitJumpInsn(GOTO, endOfIf);
- mv.visitLabel(rightIsNonNull); // stack: left/right
+ mv.visitLabel(rightIsNonNull); // stack: left/right
// here: RIGHT!=null LEFT==unknown
- mv.visitInsn(SWAP); // stack: right/left
- mv.visitInsn(DUP); // stack: right/left/left
+ mv.visitInsn(SWAP); // stack: right/left
+ mv.visitInsn(DUP); // stack: right/left/left
Label neitherRightNorLeftAreNull = new Label();
- mv.visitJumpInsn(IFNONNULL, neitherRightNorLeftAreNull); // stack: right/left
+ mv.visitJumpInsn(IFNONNULL, neitherRightNorLeftAreNull); // stack: right/left
// here: RIGHT!=null LEFT==null
- mv.visitInsn(POP2); // stack:
+ mv.visitInsn(POP2); // stack:
switch (compInstruction1) {
case IFGE: // OpLT
case IFGT: // OpLE
- mv.visitInsn(ICONST_1); // true - null is < or <= something
+ mv.visitInsn(ICONST_1); // true - null is < or <= something
break;
case IFLE: // OpGT
case IFLT: // OpGE
- mv.visitInsn(ICONST_0); // false - null is not > or >= something
+ mv.visitInsn(ICONST_0); // false - null is not > or >= something
break;
default:
- throw new IllegalStateException("Unsupported: "+compInstruction1);
+ throw new IllegalStateException("Unsupported: " + compInstruction1);
}
mv.visitJumpInsn(GOTO, endOfIf);
- mv.visitLabel(neitherRightNorLeftAreNull); // stack: right/left
+ mv.visitLabel(neitherRightNorLeftAreNull); // stack: right/left
// neither were null so unbox and proceed with numeric comparison
if (unboxLeft) {
CodeFlow.insertUnboxInsns(mv, targetType, leftDesc);
diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java
index a3fa8ea8e6f..c08bf4fa99c 100644
--- a/spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java
+++ b/spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java
@@ -4994,7 +4994,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
private void verifyCompilationAndBehaviourWithNull(String expressionText, SpelExpressionParser parser, StandardEvaluationContext ctx) {
Reg r = (Reg)ctx.getRootObject().getValue();
- r.setValue2(1); // having a value in value2 fields will enable compilation to succeed, then can switch it to null
+ r.setValue2(1); // having a value in value2 fields will enable compilation to succeed, then can switch it to null
SpelExpression fast = (SpelExpression) parser.parseExpression(expressionText);
SpelExpression slow = (SpelExpression) parser.parseExpression(expressionText);
fast.getValue(ctx);
@@ -5124,7 +5124,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
}
- // helper methods
+ // Helper methods
private SpelNodeImpl getAst() {
SpelExpression spelExpression = (SpelExpression) expression;
@@ -5196,69 +5196,7 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
}
- // nested types
-
- public class Reg {
- private Integer _value,_value2;
- private Long _valueL,_valueL2;
- private Double _valueD,_valueD2;
- private Float _valueF,_valueF2;
-
-
- public Reg(int v) {
- this._value = v;
- this._valueL = new Long(v);
- this._valueD = new Double(v);
- this._valueF = new Float(v);
- }
-
- public Integer getValue() {
- return _value;
- }
-
- public Long getValueL() {
- return _valueL;
- }
-
- public Double getValueD() {
- return _valueD;
- }
-
- public Float getValueF() {
- return _valueF;
- }
-
- public Integer getValue2() {
- return _value2;
- }
-
- public Long getValueL2() {
- return _valueL2;
- }
-
- public Double getValueD2() {
- return _valueD2;
- }
-
- public Float getValueF2() {
- return _valueF2;
- }
-
- public void setValue(Integer value) {
- _value = value;
- _valueL = value==null?null:new Long(value);
- _valueD = value==null?null:new Double(value);
- _valueF = value==null?null:new Float(value);
- }
-
- public void setValue2(Integer value) {
- _value2 = value;
- _valueL2 = value==null?null:new Long(value);
- _valueD2 = value==null?null:new Double(value);
- _valueF2 = value==null?null:new Float(value);
- }
- }
-
+ // Nested types
public interface Message {
@@ -6276,4 +6214,66 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
public Long someLong = 3L;
}
+
+ public class Reg {
+
+ private Integer _value,_value2;
+ private Long _valueL,_valueL2;
+ private Double _valueD,_valueD2;
+ private Float _valueF,_valueF2;
+
+ public Reg(int v) {
+ this._value = v;
+ this._valueL = new Long(v);
+ this._valueD = new Double(v);
+ this._valueF = new Float(v);
+ }
+
+ public Integer getValue() {
+ return _value;
+ }
+
+ public Long getValueL() {
+ return _valueL;
+ }
+
+ public Double getValueD() {
+ return _valueD;
+ }
+
+ public Float getValueF() {
+ return _valueF;
+ }
+
+ public Integer getValue2() {
+ return _value2;
+ }
+
+ public Long getValueL2() {
+ return _valueL2;
+ }
+
+ public Double getValueD2() {
+ return _valueD2;
+ }
+
+ public Float getValueF2() {
+ return _valueF2;
+ }
+
+ public void setValue(Integer value) {
+ _value = value;
+ _valueL = value==null?null:new Long(value);
+ _valueD = value==null?null:new Double(value);
+ _valueF = value==null?null:new Float(value);
+ }
+
+ public void setValue2(Integer value) {
+ _value2 = value;
+ _valueL2 = value==null?null:new Long(value);
+ _valueD2 = value==null?null:new Double(value);
+ _valueF2 = value==null?null:new Float(value);
+ }
+ }
+
}
diff --git a/spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java b/spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java
index 95cc22fc9e2..1e235ce8770 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/annotation/Propagation.java
@@ -87,11 +87,11 @@ public enum Propagation {
/**
* Execute within a nested transaction if a current transaction exists,
- * behave like {@code REQUIRED} else. There is no analogous feature in EJB.
+ * behave like {@code REQUIRED} otherwise. There is no analogous feature in EJB.
* Note: Actual creation of a nested transaction will only work on specific
* transaction managers. Out of the box, this only applies to the JDBC
- * DataSourceTransactionManager when working on a JDBC 3.0 driver.
- * Some JTA providers might support nested transactions as well.
+ * DataSourceTransactionManager. Some JTA providers might support nested
+ * transactions as well.
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager
*/
NESTED(TransactionDefinition.PROPAGATION_NESTED);
diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java
index ee75c9aea34..809a854aad2 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractPlatformTransactionManager.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.
@@ -553,7 +553,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {
return definition.getTimeout();
}
- return this.defaultTimeout;
+ return getDefaultTimeout();
}
@@ -1099,6 +1099,8 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
* @param definition a TransactionDefinition instance, describing propagation
* behavior, isolation level, read-only flag, timeout, and transaction name
* @throws TransactionException in case of creation or system errors
+ * @throws org.springframework.transaction.NestedTransactionNotSupportedException
+ * if the underlying transaction does not support nesting
*/
protected abstract void doBegin(Object transaction, TransactionDefinition definition)
throws TransactionException;
diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java b/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java
index f2aeba57c6f..19f20f8571e 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.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.
@@ -292,10 +292,11 @@ public abstract class TransactionSynchronizationManager {
throws IllegalStateException {
Assert.notNull(synchronization, "TransactionSynchronization must not be null");
- if (!isSynchronizationActive()) {
+ Set synchs = synchronizations.get();
+ if (synchs == null) {
throw new IllegalStateException("Transaction synchronization is not active");
}
- synchronizations.get().add(synchronization);
+ synchs.add(synchronization);
}
/**