diff --git a/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java b/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java index 49a84cb60a..bf726a5f9e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/MutablePropertyValues.java @@ -318,7 +318,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable { */ public void registerProcessedProperty(String propertyName) { if (this.processedProperties == null) { - this.processedProperties = new HashSet<>(); + this.processedProperties = new HashSet<>(4); } this.processedProperties.add(propertyName); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinition.java index 842c8e8c47..e798b8a399 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinition.java @@ -219,6 +219,14 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { */ ConstructorArgumentValues getConstructorArgumentValues(); + /** + * Return if there are constructor argument values defined for this bean. + * @since 5.0.2 + */ + default boolean hasConstructorArgumentValues() { + return !getConstructorArgumentValues().isEmpty(); + } + /** * Return the property values to be applied to a new instance of the bean. *

The returned instance can be modified during bean factory post-processing. @@ -226,6 +234,14 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { */ MutablePropertyValues getPropertyValues(); + /** + * Return if there are property values values defined for this bean. + * @since 5.0.2 + */ + default boolean hasPropertyValues() { + return !getPropertyValues().isEmpty(); + } + // Read-only attributes diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java index 39d571e482..77e94d7eab 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionVisitor.java @@ -81,10 +81,14 @@ public class BeanDefinitionVisitor { visitFactoryBeanName(beanDefinition); visitFactoryMethodName(beanDefinition); visitScope(beanDefinition); - visitPropertyValues(beanDefinition.getPropertyValues()); - ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues(); - visitIndexedArgumentValues(cas.getIndexedArgumentValues()); - visitGenericArgumentValues(cas.getGenericArgumentValues()); + if (beanDefinition.hasPropertyValues()) { + visitPropertyValues(beanDefinition.getPropertyValues()); + } + if (beanDefinition.hasConstructorArgumentValues()) { + ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues(); + visitIndexedArgumentValues(cas.getIndexedArgumentValues()); + visitGenericArgumentValues(cas.getGenericArgumentValues()); + } } protected void visitParentName(BeanDefinition beanDefinition) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index da5b67705b..182088403b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -723,7 +723,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac // Can't clearly figure out exact method due to type converting / autowiring! Class commonType = null; Method uniqueCandidate = null; - int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount(); + int minNrOfArgs = + (mbd.hasConstructorArgumentValues() ? mbd.getConstructorArgumentValues().getArgumentCount() : 0); Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass); for (Method factoryMethod : candidates) { if (Modifier.isStatic(factoryMethod.getModifiers()) == isStatic && @@ -1277,10 +1278,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac * @param bw BeanWrapper with bean instance */ protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { - PropertyValues pvs = mbd.getPropertyValues(); - if (bw == null) { - if (!pvs.isEmpty()) { + if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } @@ -1311,6 +1310,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac return; } + PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); + if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); @@ -1332,6 +1333,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { + if (pvs == null) { + pvs = mbd.getPropertyValues(); + } PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { @@ -1349,7 +1353,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } } - applyPropertyValues(beanName, mbd, bw, pvs); + if (pvs != null) { + applyPropertyValues(beanName, mbd, bw, pvs); + } } /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java index 782b299a1c..cfa57d8436 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java @@ -173,11 +173,14 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess @Nullable private String factoryMethodName; + @Nullable private ConstructorArgumentValues constructorArgumentValues; + @Nullable private MutablePropertyValues propertyValues; - private MethodOverrides methodOverrides = new MethodOverrides(); + @Nullable + private MethodOverrides methodOverrides; @Nullable private String initMethodName; @@ -212,8 +215,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess * constructor argument values and property values. */ protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) { - this.constructorArgumentValues = (cargs != null ? cargs : new ConstructorArgumentValues()); - this.propertyValues = (pvs != null ? pvs : new MutablePropertyValues()); + this.constructorArgumentValues = cargs; + this.propertyValues = pvs; } /** @@ -229,8 +232,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess setLazyInit(original.isLazyInit()); setFactoryBeanName(original.getFactoryBeanName()); setFactoryMethodName(original.getFactoryMethodName()); - this.constructorArgumentValues = new ConstructorArgumentValues(original.getConstructorArgumentValues()); - this.propertyValues = new MutablePropertyValues(original.getPropertyValues()); setRole(original.getRole()); setSource(original.getSource()); copyAttributesFrom(original); @@ -240,6 +241,15 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess if (originalAbd.hasBeanClass()) { setBeanClass(originalAbd.getBeanClass()); } + if (originalAbd.hasConstructorArgumentValues()) { + setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues())); + } + if (originalAbd.hasPropertyValues()) { + setPropertyValues(new MutablePropertyValues(original.getPropertyValues())); + } + if (originalAbd.hasMethodOverrides()) { + setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides())); + } setAutowireMode(originalAbd.getAutowireMode()); setDependencyCheck(originalAbd.getDependencyCheck()); setDependsOn(originalAbd.getDependsOn()); @@ -249,7 +259,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess setInstanceSupplier(originalAbd.getInstanceSupplier()); setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed()); setLenientConstructorResolution(originalAbd.isLenientConstructorResolution()); - setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides())); setInitMethodName(originalAbd.getInitMethodName()); setEnforceInitMethod(originalAbd.isEnforceInitMethod()); setDestroyMethodName(originalAbd.getDestroyMethodName()); @@ -258,6 +267,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess setResource(originalAbd.getResource()); } else { + setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues())); + setPropertyValues(new MutablePropertyValues(original.getPropertyValues())); setResourceDescription(original.getResourceDescription()); } } @@ -294,8 +305,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess if (StringUtils.hasLength(other.getFactoryMethodName())) { setFactoryMethodName(other.getFactoryMethodName()); } - getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues()); - getPropertyValues().addPropertyValues(other.getPropertyValues()); setRole(other.getRole()); setSource(other.getSource()); copyAttributesFrom(other); @@ -305,6 +314,15 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess if (otherAbd.hasBeanClass()) { setBeanClass(otherAbd.getBeanClass()); } + if (otherAbd.hasConstructorArgumentValues()) { + getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues()); + } + if (otherAbd.hasPropertyValues()) { + getPropertyValues().addPropertyValues(other.getPropertyValues()); + } + if (otherAbd.hasMethodOverrides()) { + getMethodOverrides().addOverrides(otherAbd.getMethodOverrides()); + } setAutowireMode(otherAbd.getAutowireMode()); setDependencyCheck(otherAbd.getDependencyCheck()); setDependsOn(otherAbd.getDependsOn()); @@ -314,7 +332,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess setInstanceSupplier(otherAbd.getInstanceSupplier()); setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed()); setLenientConstructorResolution(otherAbd.isLenientConstructorResolution()); - getMethodOverrides().addOverrides(otherAbd.getMethodOverrides()); if (otherAbd.getInitMethodName() != null) { setInitMethodName(otherAbd.getInitMethodName()); setEnforceInitMethod(otherAbd.isEnforceInitMethod()); @@ -327,6 +344,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess setResource(otherAbd.getResource()); } else { + getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues()); + getPropertyValues().addPropertyValues(other.getPropertyValues()); setResourceDescription(other.getResourceDescription()); } } @@ -778,9 +797,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess /** * Specify constructor argument values for this bean. */ - public void setConstructorArgumentValues(@Nullable ConstructorArgumentValues constructorArgumentValues) { - this.constructorArgumentValues = - (constructorArgumentValues != null ? constructorArgumentValues : new ConstructorArgumentValues()); + public void setConstructorArgumentValues(ConstructorArgumentValues constructorArgumentValues) { + this.constructorArgumentValues = constructorArgumentValues; } /** @@ -788,6 +806,9 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess */ @Override public ConstructorArgumentValues getConstructorArgumentValues() { + if (this.constructorArgumentValues == null) { + this.constructorArgumentValues = new ConstructorArgumentValues(); + } return this.constructorArgumentValues; } @@ -795,14 +816,14 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess * Return if there are constructor argument values defined for this bean. */ public boolean hasConstructorArgumentValues() { - return !this.constructorArgumentValues.isEmpty(); + return (this.constructorArgumentValues != null && !this.constructorArgumentValues.isEmpty()); } /** * Specify property values for this bean, if any. */ - public void setPropertyValues(@Nullable MutablePropertyValues propertyValues) { - this.propertyValues = (propertyValues != null ? propertyValues : new MutablePropertyValues()); + public void setPropertyValues(MutablePropertyValues propertyValues) { + this.propertyValues = propertyValues; } /** @@ -810,14 +831,25 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess */ @Override public MutablePropertyValues getPropertyValues() { + if (this.propertyValues == null) { + this.propertyValues = new MutablePropertyValues(); + } return this.propertyValues; } + /** + * Return if there are property values values defined for this bean. + * @since 5.0.2 + */ + public boolean hasPropertyValues() { + return (this.propertyValues != null && !this.propertyValues.isEmpty()); + } + /** * Specify method overrides for the bean, if any. */ - public void setMethodOverrides(@Nullable MethodOverrides methodOverrides) { - this.methodOverrides = (methodOverrides != null ? methodOverrides : new MethodOverrides()); + public void setMethodOverrides(MethodOverrides methodOverrides) { + this.methodOverrides = methodOverrides; } /** @@ -826,9 +858,20 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess *

Never returns {@code null}. */ public MethodOverrides getMethodOverrides() { + if (this.methodOverrides == null) { + this.methodOverrides = new MethodOverrides(); + } return this.methodOverrides; } + /** + * Return if there are method overrides defined for this bean. + * @since 5.0.2 + */ + public boolean hasMethodOverrides() { + return (this.methodOverrides != null && !this.methodOverrides.isEmpty()); + } + /** * Set the name of the initializer method. *

The default is {@code null} in which case there is no initializer method. @@ -1002,7 +1045,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess * @throws BeanDefinitionValidationException in case of validation failure */ public void validate() throws BeanDefinitionValidationException { - if (!getMethodOverrides().isEmpty() && getFactoryMethodName() != null) { + if (hasMethodOverrides() && getFactoryMethodName() != null) { throw new BeanDefinitionValidationException( "Cannot combine static factory method with method overrides: " + "the static factory method must create the instance"); @@ -1020,9 +1063,8 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess */ public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exists. - MethodOverrides methodOverrides = getMethodOverrides(); - if (!methodOverrides.isEmpty()) { - Set overrides = methodOverrides.getOverrides(); + if (hasMethodOverrides()) { + Set overrides = getMethodOverrides().getOverrides(); synchronized (overrides) { for (MethodOverride mo : overrides) { prepareMethodOverride(mo); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java index 090d372518..219d8f75ca 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java @@ -434,9 +434,14 @@ class ConstructorResolver { else { // We don't have arguments passed in programmatically, so we need to resolve the // arguments specified in the constructor arguments held in the bean definition. - ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); - resolvedValues = new ConstructorArgumentValues(); - minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); + if (mbd.hasConstructorArgumentValues()) { + ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); + resolvedValues = new ConstructorArgumentValues(); + minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); + } + else { + minNrOfArgs = 0; + } } LinkedList causes = null; @@ -447,7 +452,14 @@ class ConstructorResolver { if (paramTypes.length >= minNrOfArgs) { ArgumentsHolder argsHolder; - if (resolvedValues != null) { + if (explicitArgs != null){ + // Explicit arguments given -> arguments length must match exactly. + if (paramTypes.length != explicitArgs.length) { + continue; + } + argsHolder = new ArgumentsHolder(explicitArgs); + } + else { // Resolved constructor arguments: type conversion and/or autowiring necessary. try { String[] paramNames = null; @@ -472,14 +484,6 @@ class ConstructorResolver { } } - else { - // Explicit arguments given -> arguments length must match exactly. - if (paramTypes.length != explicitArgs.length) { - continue; - } - argsHolder = new ArgumentsHolder(explicitArgs); - } - int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); // Choose this factory method if it represents the closest match. @@ -522,7 +526,7 @@ class ConstructorResolver { argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null"); } } - else { + else if (resolvedValues != null){ Set valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount()); valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values()); valueHolders.addAll(resolvedValues.getGenericArgumentValues()); @@ -645,7 +649,7 @@ class ConstructorResolver { * given the resolved constructor argument values. */ private ArgumentsHolder createArgumentArray( - String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues, + String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues, BeanWrapper bw, Class[] paramTypes, @Nullable String[] paramNames, Executable executable, boolean autowiring) throws UnsatisfiedDependencyException { @@ -660,13 +664,15 @@ class ConstructorResolver { Class paramType = paramTypes[paramIndex]; String paramName = (paramNames != null ? paramNames[paramIndex] : ""); // Try to find matching constructor argument value, either indexed or generic. - ConstructorArgumentValues.ValueHolder valueHolder = - resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders); - // If we couldn't find a direct match and are not supposed to autowire, - // let's try the next generic, untyped argument value as fallback: - // it could match after type conversion (for example, String -> int). - if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) { - valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders); + ConstructorArgumentValues.ValueHolder valueHolder = null; + if (resolvedValues != null) { + valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders); + // If we couldn't find a direct match and are not supposed to autowire, + // let's try the next generic, untyped argument value as fallback: + // it could match after type conversion (for example, String -> int). + if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) { + valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders); + } } if (valueHolder != null) { // We found a potential match - let's give it a try. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java index 41f2d2ec23..0e1c942f5b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverrides.java @@ -37,7 +37,7 @@ import org.springframework.lang.Nullable; */ public class MethodOverrides { - private final Set overrides = Collections.synchronizedSet(new LinkedHashSet<>(0)); + private final Set overrides = Collections.synchronizedSet(new LinkedHashSet<>(2)); private volatile boolean modified = false; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java index 927128e966..348be8baf0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java @@ -190,7 +190,9 @@ public class RootBeanDefinition extends AbstractBeanDefinition { * @param cargs the constructor argument values to apply * @param pvs the property values to apply */ - public RootBeanDefinition(@Nullable Class beanClass, ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) { + public RootBeanDefinition(@Nullable Class beanClass, @Nullable ConstructorArgumentValues cargs, + @Nullable MutablePropertyValues pvs) { + super(cargs, pvs); setBeanClass(beanClass); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java index fecdb77eff..0b223f1fa3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java @@ -60,7 +60,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { @Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. - if (bd.getMethodOverrides().isEmpty()) { + if (!bd.hasMethodOverrides()) { Constructor constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod; @@ -72,8 +72,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged( - (PrivilegedExceptionAction>) () -> - clazz.getDeclaredConstructor()); + (PrivilegedExceptionAction>) () -> clazz.getDeclaredConstructor()); } else { constructorToUse = clazz.getDeclaredConstructor(); @@ -107,7 +106,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, final Constructor ctor, @Nullable Object... args) { - if (bd.getMethodOverrides().isEmpty()) { + if (!bd.hasMethodOverrides()) { if (System.getSecurityManager() != null) { // use own privileged to change accessibility (when security is on) AccessController.doPrivileged((PrivilegedAction) () -> { diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheCustomInterceptorTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheCustomInterceptorTests.java index 2c14da4e52..2576dc71c2 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheCustomInterceptorTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheCustomInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -41,7 +41,6 @@ import org.springframework.context.annotation.Configuration; import static org.junit.Assert.*; /** - * * @author Stephane Nicoll */ public class JCacheCustomInterceptorTests { @@ -52,6 +51,7 @@ public class JCacheCustomInterceptorTests { protected Cache exceptionCache; + @Before public void setup() { ctx = new AnnotationConfigApplicationContext(EnableCachingConfig.class); @@ -61,9 +61,12 @@ public class JCacheCustomInterceptorTests { @After public void tearDown() { - ctx.close(); + if (ctx != null) { + ctx.close(); + } } + @Test public void onlyOneInterceptorIsAvailable() { Map interceptors = ctx.getBeansOfType(JCacheInterceptor.class); @@ -130,6 +133,7 @@ public class JCacheCustomInterceptorTests { } } + /** * A test {@link org.springframework.cache.interceptor.CacheInterceptor} that handles special exception * types. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java index 9719af77c8..eea0df9962 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java @@ -291,24 +291,24 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { String resourceCache = element.getAttribute("resource-cache"); if ("true".equals(resourceCache)) { - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); RootBeanDefinition cachingResolverDef = new RootBeanDefinition(CachingResourceResolver.class); cachingResolverDef.setSource(source); cachingResolverDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - cachingResolverDef.setConstructorArgumentValues(cavs); + cachingResolverDef.setConstructorArgumentValues(cargs); RootBeanDefinition cachingTransformerDef = new RootBeanDefinition(CachingResourceTransformer.class); cachingTransformerDef.setSource(source); cachingTransformerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - cachingTransformerDef.setConstructorArgumentValues(cavs); + cachingTransformerDef.setConstructorArgumentValues(cargs); String cacheManagerName = element.getAttribute("cache-manager"); String cacheName = element.getAttribute("cache-name"); if (StringUtils.hasText(cacheManagerName) && StringUtils.hasText(cacheName)) { RuntimeBeanReference cacheManagerRef = new RuntimeBeanReference(cacheManagerName); - cavs.addIndexedArgumentValue(0, cacheManagerRef); - cavs.addIndexedArgumentValue(1, cacheName); + cargs.addIndexedArgumentValue(0, cacheManagerRef); + cargs.addIndexedArgumentValue(1, cacheName); } else { ConstructorArgumentValues cacheCavs = new ConstructorArgumentValues(); @@ -317,7 +317,7 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { cacheDef.setSource(source); cacheDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); cacheDef.setConstructorArgumentValues(cacheCavs); - cavs.addIndexedArgumentValue(0, cacheDef); + cargs.addIndexedArgumentValue(0, cacheDef); } resourceResolvers.add(cachingResolverDef); resourceTransformers.add(cachingTransformerDef); @@ -386,12 +386,12 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { String[] patterns = StringUtils.commaDelimitedListToStringArray(beanElement.getAttribute("patterns")); Object strategy = null; if (FIXED_VERSION_STRATEGY_ELEMENT.equals(beanElement.getLocalName())) { - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, beanElement.getAttribute("version")); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, beanElement.getAttribute("version")); RootBeanDefinition strategyDef = new RootBeanDefinition(FixedVersionStrategy.class); strategyDef.setSource(source); strategyDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - strategyDef.setConstructorArgumentValues(cavs); + strategyDef.setConstructorArgumentValues(cargs); strategy = strategyDef; } else if (CONTENT_VERSION_STRATEGY_ELEMENT.equals(beanElement.getLocalName())) { diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/HandlersBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/HandlersBeanDefinitionParser.java index 61141644a3..5c0ad0b498 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/HandlersBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/HandlersBeanDefinitionParser.java @@ -105,16 +105,16 @@ class HandlersBeanDefinitionParser implements BeanDefinitionParser { private interface HandlerMappingStrategy { void addMapping(Element mappingElement, ManagedMap map, ParserContext context); - } + private static class WebSocketHandlerMappingStrategy implements HandlerMappingStrategy { private final RuntimeBeanReference handshakeHandlerReference; private final ManagedList interceptorsList; - private WebSocketHandlerMappingStrategy(RuntimeBeanReference handshakeHandler, ManagedList interceptors) { + public WebSocketHandlerMappingStrategy(RuntimeBeanReference handshakeHandler, ManagedList interceptors) { this.handshakeHandlerReference = handshakeHandler; this.interceptorsList = interceptors; } @@ -125,10 +125,10 @@ class HandlersBeanDefinitionParser implements BeanDefinitionParser { List mappings = Arrays.asList(StringUtils.tokenizeToStringArray(pathAttribute, ",")); RuntimeBeanReference handlerReference = new RuntimeBeanReference(element.getAttribute("handler")); - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, handlerReference); - cavs.addIndexedArgumentValue(1, this.handshakeHandlerReference); - RootBeanDefinition requestHandlerDef = new RootBeanDefinition(WebSocketHttpRequestHandler.class, cavs, null); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, handlerReference); + cargs.addIndexedArgumentValue(1, this.handshakeHandlerReference); + RootBeanDefinition requestHandlerDef = new RootBeanDefinition(WebSocketHttpRequestHandler.class, cargs, null); requestHandlerDef.setSource(context.extractSource(element)); requestHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); requestHandlerDef.getPropertyValues().add("handshakeInterceptors", this.interceptorsList); @@ -141,12 +141,12 @@ class HandlersBeanDefinitionParser implements BeanDefinitionParser { } } + private static class SockJsHandlerMappingStrategy implements HandlerMappingStrategy { private final RuntimeBeanReference sockJsService; - - private SockJsHandlerMappingStrategy(RuntimeBeanReference sockJsService) { + public SockJsHandlerMappingStrategy(RuntimeBeanReference sockJsService) { this.sockJsService = sockJsService; } @@ -156,11 +156,11 @@ class HandlersBeanDefinitionParser implements BeanDefinitionParser { List mappings = Arrays.asList(StringUtils.tokenizeToStringArray(pathAttribute, ",")); RuntimeBeanReference handlerReference = new RuntimeBeanReference(element.getAttribute("handler")); - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, this.sockJsService, "SockJsService"); - cavs.addIndexedArgumentValue(1, handlerReference, "WebSocketHandler"); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, this.sockJsService, "SockJsService"); + cargs.addIndexedArgumentValue(1, handlerReference, "WebSocketHandler"); - RootBeanDefinition requestHandlerDef = new RootBeanDefinition(SockJsHttpRequestHandler.class, cavs, null); + RootBeanDefinition requestHandlerDef = new RootBeanDefinition(SockJsHttpRequestHandler.class, cargs, null); requestHandlerDef.setSource(context.extractSource(element)); requestHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); String requestHandlerName = context.getReaderContext().registerWithGeneratedName(requestHandlerDef); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java index 684a01727e..b8658491a7 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java @@ -243,14 +243,14 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { } } } - ConstructorArgumentValues argValues = new ConstructorArgumentValues(); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); if (executor != null) { executor.getPropertyValues().add("threadNamePrefix", name + "-"); String executorName = name + "Executor"; registerBeanDefByName(executorName, executor, context, source); - argValues.addIndexedArgumentValue(0, new RuntimeBeanReference(executorName)); + cargs.addIndexedArgumentValue(0, new RuntimeBeanReference(executorName)); } - RootBeanDefinition channelDef = new RootBeanDefinition(ExecutorSubscribableChannel.class, argValues, null); + RootBeanDefinition channelDef = new RootBeanDefinition(ExecutorSubscribableChannel.class, cargs, null); ManagedList interceptors = new ManagedList<>(); if (element != null) { Element interceptorsElement = DomUtils.getChildElementByTagName(element, "interceptors"); @@ -288,11 +288,11 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { stompHandlerDef.getPropertyValues().add("errorHandler", errorHandlerRef); } - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, inChannel); - cavs.addIndexedArgumentValue(1, outChannel); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, inChannel); + cargs.addIndexedArgumentValue(1, outChannel); - RootBeanDefinition handlerDef = new RootBeanDefinition(SubProtocolWebSocketHandler.class, cavs, null); + RootBeanDefinition handlerDef = new RootBeanDefinition(SubProtocolWebSocketHandler.class, cargs, null); handlerDef.getPropertyValues().addPropertyValue("protocolHandlers", stompHandlerDef); registerBeanDefByName(WEB_SOCKET_HANDLER_BEAN_NAME, handlerDef, context, source); RuntimeBeanReference result = new RuntimeBeanReference(WEB_SOCKET_HANDLER_BEAN_NAME); @@ -329,10 +329,10 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { element, SCHEDULER_BEAN_NAME, cxt, source); if (sockJsService != null) { - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, sockJsService); - cavs.addIndexedArgumentValue(1, subProtoHandler); - beanDef = new RootBeanDefinition(SockJsHttpRequestHandler.class, cavs, null); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, sockJsService); + cargs.addIndexedArgumentValue(1, subProtoHandler); + beanDef = new RootBeanDefinition(SockJsHttpRequestHandler.class, cargs, null); // Register alias for backwards compatibility with 4.1 cxt.getRegistry().registerAlias(SCHEDULER_BEAN_NAME, SOCKJS_SCHEDULER_BEAN_NAME); @@ -344,10 +344,10 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { String allowedOrigins = element.getAttribute("allowed-origins"); List origins = Arrays.asList(StringUtils.tokenizeToStringArray(allowedOrigins, ",")); interceptors.add(new OriginHandshakeInterceptor(origins)); - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, subProtoHandler); - cavs.addIndexedArgumentValue(1, handler); - beanDef = new RootBeanDefinition(WebSocketHttpRequestHandler.class, cavs, null); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, subProtoHandler); + cargs.addIndexedArgumentValue(1, handler); + beanDef = new RootBeanDefinition(WebSocketHttpRequestHandler.class, cargs, null); beanDef.getPropertyValues().add("handshakeInterceptors", interceptors); } return new RuntimeBeanReference(registerBeanDef(beanDef, cxt, source)); @@ -361,16 +361,16 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { Element simpleBrokerElem = DomUtils.getChildElementByTagName(brokerElement, "simple-broker"); Element brokerRelayElem = DomUtils.getChildElementByTagName(brokerElement, "stomp-broker-relay"); - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, inChannel); - cavs.addIndexedArgumentValue(1, outChannel); - cavs.addIndexedArgumentValue(2, brokerChannel); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, inChannel); + cargs.addIndexedArgumentValue(1, outChannel); + cargs.addIndexedArgumentValue(2, brokerChannel); RootBeanDefinition brokerDef; if (simpleBrokerElem != null) { String prefix = simpleBrokerElem.getAttribute("prefix"); - cavs.addIndexedArgumentValue(3, Arrays.asList(StringUtils.tokenizeToStringArray(prefix, ","))); - brokerDef = new RootBeanDefinition(SimpleBrokerMessageHandler.class, cavs, null); + cargs.addIndexedArgumentValue(3, Arrays.asList(StringUtils.tokenizeToStringArray(prefix, ","))); + brokerDef = new RootBeanDefinition(SimpleBrokerMessageHandler.class, cargs, null); if (brokerElement.hasAttribute("path-matcher")) { String pathMatcherRef = brokerElement.getAttribute("path-matcher"); brokerDef.getPropertyValues().add("pathMatcher", new RuntimeBeanReference(pathMatcherRef)); @@ -386,7 +386,7 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { } else if (brokerRelayElem != null) { String prefix = brokerRelayElem.getAttribute("prefix"); - cavs.addIndexedArgumentValue(3, Arrays.asList(StringUtils.tokenizeToStringArray(prefix, ","))); + cargs.addIndexedArgumentValue(3, Arrays.asList(StringUtils.tokenizeToStringArray(prefix, ","))); MutablePropertyValues values = new MutablePropertyValues(); if (brokerRelayElem.hasAttribute("relay-host")) { @@ -431,7 +431,7 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { values.add("systemSubscriptions", map); } Class handlerType = StompBrokerRelayMessageHandler.class; - brokerDef = new RootBeanDefinition(handlerType, cavs, values); + brokerDef = new RootBeanDefinition(handlerType, cargs, values); } else { // Should not happen @@ -487,9 +487,9 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { converters.add(jacksonConverterDef); } } - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, converters); - RootBeanDefinition messageConverterDef = new RootBeanDefinition(CompositeMessageConverter.class, cavs, null); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, converters); + RootBeanDefinition messageConverterDef = new RootBeanDefinition(CompositeMessageConverter.class, cargs, null); String name = MESSAGE_CONVERTER_BEAN_NAME; registerBeanDefByName(name, messageConverterDef, context, source); return new RuntimeBeanReference(name); @@ -498,9 +498,9 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { private RuntimeBeanReference registerMessagingTemplate(Element element, RuntimeBeanReference brokerChannel, RuntimeBeanReference messageConverter, ParserContext context, @Nullable Object source) { - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, brokerChannel); - RootBeanDefinition beanDef = new RootBeanDefinition(SimpMessagingTemplate.class,cavs, null); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, brokerChannel); + RootBeanDefinition beanDef = new RootBeanDefinition(SimpMessagingTemplate.class, cargs, null); if (element.hasAttribute("user-destination-prefix")) { beanDef.getPropertyValues().add("userDestinationPrefix", element.getAttribute("user-destination-prefix")); } @@ -515,17 +515,17 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { RuntimeBeanReference converter, RuntimeBeanReference messagingTemplate, ParserContext context, @Nullable Object source) { - ConstructorArgumentValues cavs = new ConstructorArgumentValues(); - cavs.addIndexedArgumentValue(0, inChannel); - cavs.addIndexedArgumentValue(1, outChannel); - cavs.addIndexedArgumentValue(2, messagingTemplate); + ConstructorArgumentValues cargs = new ConstructorArgumentValues(); + cargs.addIndexedArgumentValue(0, inChannel); + cargs.addIndexedArgumentValue(1, outChannel); + cargs.addIndexedArgumentValue(2, messagingTemplate); MutablePropertyValues values = new MutablePropertyValues(); String prefixAttribute = messageBrokerElement.getAttribute("application-destination-prefix"); values.add("destinationPrefixes", Arrays.asList(StringUtils.tokenizeToStringArray(prefixAttribute, ","))); values.add("messageConverter", converter); - RootBeanDefinition beanDef = new RootBeanDefinition(WebSocketAnnotationMethodMessageHandler.class, cavs, values); + RootBeanDefinition beanDef = new RootBeanDefinition(WebSocketAnnotationMethodMessageHandler.class, cargs, values); if (messageBrokerElement.hasAttribute("path-matcher")) { String pathMatcherRef = messageBrokerElement.getAttribute("path-matcher"); beanDef.getPropertyValues().add("pathMatcher", new RuntimeBeanReference(pathMatcherRef));