diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java b/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java index 5066acefe9..16c6bae560 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyValue.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. @@ -169,7 +169,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri } /** - * Set the converted value of the constructor argument, + * Set the converted value of this property value, * after processed type conversion. */ public synchronized void setConvertedValue(@Nullable Object value) { @@ -178,7 +178,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri } /** - * Return the converted value of the constructor argument, + * Return the converted value of this property value, * after processed type conversion. */ @Nullable diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java b/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java index 37451bdce0..13e765893d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java @@ -180,7 +180,7 @@ public class InjectionPoint { if (this == other) { return true; } - if (getClass() != other.getClass()) { + if (other == null || getClass() != other.getClass()) { return false; } InjectionPoint otherPoint = (InjectionPoint) other; 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 8e2c30919d..7b826c50d7 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 @@ -234,7 +234,7 @@ public class BeanDefinitionVisitor { } } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) protected void visitList(List listVal) { for (int i = 0; i < listVal.size(); i++) { Object elem = listVal.get(i); @@ -245,7 +245,7 @@ public class BeanDefinitionVisitor { } } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) protected void visitSet(Set setVal) { Set newContent = new LinkedHashSet(); boolean entriesModified = false; @@ -262,7 +262,7 @@ public class BeanDefinitionVisitor { } } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) protected void visitMap(Map mapVal) { Map newContent = new LinkedHashMap(); boolean entriesModified = false; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlMapFactoryBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlMapFactoryBean.java index 1e20063ccc..bc77a9f7c1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlMapFactoryBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlMapFactoryBean.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. @@ -117,7 +117,7 @@ public class YamlMapFactoryBean extends YamlProcessor implements FactoryBeanThe default implementation returns the merged {@code Map} instance. * @return the object returned by this factory - * @see #process(java.util.Map, MatchCallback) + * @see #process(MatchCallback) */ protected Map createMap() { Map result = new LinkedHashMap<>(); @@ -125,7 +125,7 @@ public class YamlMapFactoryBean extends YamlProcessor implements FactoryBean output, Map map) { map.forEach((key, value) -> { Object existing = output.get(key); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlPropertiesFactoryBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlPropertiesFactoryBean.java index 200f78c4c9..71088f17f0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlPropertiesFactoryBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlPropertiesFactoryBean.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. @@ -128,7 +128,7 @@ public class YamlPropertiesFactoryBean extends YamlProcessor implements FactoryB *

Invoked lazily the first time {@link #getObject()} is invoked in * case of a shared singleton; else, on each {@link #getObject()} call. * @return the object returned by this factory - * @see #process(MatchCallback) () + * @see #process(MatchCallback) */ protected Properties createProperties() { Properties result = CollectionFactory.createStringAdaptingProperties(); 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 f59ca87481..ebdaa91644 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 @@ -1873,7 +1873,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac String initMethodName = mbd.getInitMethodName(); Assert.state(initMethodName != null, "No init method set"); - final Method initMethod = (mbd.isNonPublicAccessAllowed() ? + Method initMethod = (mbd.isNonPublicAccessAllowed() ? BeanUtils.findMethod(bean.getClass(), initMethodName) : ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName)); @@ -1895,15 +1895,16 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac if (logger.isTraceEnabled()) { logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'"); } + Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod); if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { - ReflectionUtils.makeAccessible(initMethod); + ReflectionUtils.makeAccessible(methodToInvoke); return null; }); try { AccessController.doPrivileged((PrivilegedExceptionAction) () -> - initMethod.invoke(bean), getAccessControlContext()); + methodToInvoke.invoke(bean), getAccessControlContext()); } catch (PrivilegedActionException pae) { InvocationTargetException ex = (InvocationTargetException) pae.getException(); 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 a9c3216b5d..e35aa60ec8 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 @@ -65,7 +65,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess public static final String SCOPE_DEFAULT = ""; /** - * Constant that indicates no autowiring at all. + * Constant that indicates no external autowiring at all. * @see #setAutowireMode */ public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java index dcd428cb71..5b4c3ba9ec 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.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. @@ -181,6 +181,8 @@ public final class BeanDefinitionBuilder { /** * Set the name of a non-static factory method to use for this definition, * including the bean name of the factory instance to call the method on. + * @param factoryMethod the name of the factory method + * @param factoryBean the name of the bean to call the specified factory method on * @since 4.3.6 */ public BeanDefinitionBuilder setFactoryMethodOnBean(String factoryMethod, String factoryBean) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java index 7739b7c5d4..59ee973917 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.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. @@ -176,7 +176,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt @Override public boolean equals(@Nullable Object other) { - return (getClass() == other.getClass() && + return (other != null && getClass() == other.getClass() && this.beanDefinition.equals(((CglibIdentitySupport) other).beanDefinition)); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java index e8fc4ce2d7..9d1ce3466c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.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. @@ -112,15 +112,15 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) && !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) { this.destroyMethodName = destroyMethodName; - this.destroyMethod = determineDestroyMethod(destroyMethodName); - if (this.destroyMethod == null) { + Method destroyMethod = determineDestroyMethod(destroyMethodName); + if (destroyMethod == null) { if (beanDefinition.isEnforceDestroyMethod()) { throw new BeanDefinitionValidationException("Could not find a destroy method named '" + destroyMethodName + "' on bean with name '" + beanName + "'"); } } else { - Class[] paramTypes = this.destroyMethod.getParameterTypes(); + Class[] paramTypes = destroyMethod.getParameterTypes(); if (paramTypes.length > 1) { throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + beanName + "' has more than one parameter - not supported as destroy method"); @@ -129,7 +129,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + beanName + "' has a non-boolean parameter - not supported as destroy method"); } + destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod); } + this.destroyMethod = destroyMethod; } this.beanPostProcessors = filterPostProcessors(postProcessors, bean); } @@ -271,9 +273,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { - Method methodToCall = determineDestroyMethod(this.destroyMethodName); - if (methodToCall != null) { - invokeCustomDestroyMethod(methodToCall); + Method methodToInvoke = determineDestroyMethod(this.destroyMethodName); + if (methodToInvoke != null) { + invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionBuilderTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionBuilderTests.java index c0642fc1f6..a0f0c3e786 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionBuilderTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionBuilderTests.java @@ -36,9 +36,9 @@ public class BeanDefinitionBuilderTests { String[] dependsOn = new String[] { "A", "B", "C" }; BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class); bdb.setScope(BeanDefinition.SCOPE_PROTOTYPE); - bdb.addPropertyReference("age", "15"); - for (int i = 0; i < dependsOn.length; i++) { - bdb.addDependsOn(dependsOn[i]); + bdb.addPropertyValue("age", "15"); + for (String dependsOnEntry : dependsOn) { + bdb.addDependsOn(dependsOnEntry); } RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition(); diff --git a/spring-beans/src/test/java/org/springframework/tests/sample/beans/TestBean.java b/spring-beans/src/test/java/org/springframework/tests/sample/beans/TestBean.java index 3425c43389..1e83a21a13 100644 --- a/spring-beans/src/test/java/org/springframework/tests/sample/beans/TestBean.java +++ b/spring-beans/src/test/java/org/springframework/tests/sample/beans/TestBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -61,8 +61,6 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt private ITestBean spouse; - protected ITestBean[] spouses; - private String touchy; private String[] stringArray; diff --git a/spring-context/src/main/java/org/springframework/context/event/SimpleApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/SimpleApplicationEventMulticaster.java index f62ed6a9aa..cb70ac4ea0 100644 --- a/spring-context/src/main/java/org/springframework/context/event/SimpleApplicationEventMulticaster.java +++ b/spring-context/src/main/java/org/springframework/context/event/SimpleApplicationEventMulticaster.java @@ -166,7 +166,7 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM } } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) { try { listener.onApplicationEvent(event); diff --git a/spring-core/src/main/java/org/springframework/core/CollectionFactory.java b/spring-core/src/main/java/org/springframework/core/CollectionFactory.java index d131fd2727..084037c1e6 100644 --- a/spring-core/src/main/java/org/springframework/core/CollectionFactory.java +++ b/spring-core/src/main/java/org/springframework/core/CollectionFactory.java @@ -241,7 +241,7 @@ public final class CollectionFactory { * @see java.util.TreeMap * @see java.util.LinkedHashMap */ - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public static Map createApproximateMap(@Nullable Object map, int capacity) { if (map instanceof EnumMap) { EnumMap enumMap = new EnumMap((EnumMap) map); @@ -294,7 +294,7 @@ public final class CollectionFactory { * {@code null}; or if the desired {@code mapType} is {@link EnumMap} and * the supplied {@code keyType} is not a subtype of {@link Enum} */ - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public static Map createMap(Class mapType, @Nullable Class keyType, int capacity) { Assert.notNull(mapType, "Map type must not be null"); if (mapType.isInterface()) { diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/IntegerToEnumConverterFactory.java b/spring-core/src/main/java/org/springframework/core/convert/support/IntegerToEnumConverterFactory.java index a7acc3a6d5..4322d8ebb3 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/IntegerToEnumConverterFactory.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/IntegerToEnumConverterFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 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. @@ -26,7 +26,7 @@ import org.springframework.core.convert.converter.ConverterFactory; * @author Stephane Nicoll * @since 4.3 */ -@SuppressWarnings({"unchecked", "rawtypes"}) +@SuppressWarnings({"rawtypes", "unchecked"}) final class IntegerToEnumConverterFactory implements ConverterFactory { @Override diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java b/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java index 90895bc1e6..6a0c3ba395 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java @@ -26,7 +26,7 @@ import org.springframework.core.convert.converter.ConverterFactory; * @author Stephane Nicoll * @since 3.0 */ -@SuppressWarnings({"unchecked", "rawtypes"}) +@SuppressWarnings({"rawtypes", "unchecked"}) final class StringToEnumConverterFactory implements ConverterFactory { @Override diff --git a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java index 1d69b41ac4..e13e03ed0f 100644 --- a/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.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. @@ -383,7 +383,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { } @Override - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public Map getSystemProperties() { try { return (Map) System.getProperties(); @@ -409,7 +409,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment { } @Override - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public Map getSystemEnvironment() { if (suppressGetenvAccess()) { return Collections.emptyMap(); diff --git a/spring-core/src/main/java/org/springframework/core/env/PropertiesPropertySource.java b/spring-core/src/main/java/org/springframework/core/env/PropertiesPropertySource.java index 0d023fe336..d09c368351 100644 --- a/spring-core/src/main/java/org/springframework/core/env/PropertiesPropertySource.java +++ b/spring-core/src/main/java/org/springframework/core/env/PropertiesPropertySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 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. @@ -35,7 +35,7 @@ import java.util.Properties; */ public class PropertiesPropertySource extends MapPropertySource { - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public PropertiesPropertySource(String name, Properties source) { super(name, (Map) source); } @@ -44,4 +44,12 @@ public class PropertiesPropertySource extends MapPropertySource { super(name, source); } + + @Override + public String[] getPropertyNames() { + synchronized (this.source) { + return super.getPropertyNames(); + } + } + } diff --git a/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java b/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java index 179e1d7b5a..fc4570684d 100644 --- a/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.java +++ b/spring-core/src/main/java/org/springframework/core/env/StandardEnvironment.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. @@ -75,8 +75,10 @@ public class StandardEnvironment extends AbstractEnvironment { */ @Override protected void customizePropertySources(MutablePropertySources propertySources) { - propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); - propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); + propertySources.addLast( + new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); + propertySources.addLast( + new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); } } diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java index 503f7af485..c1fa0f7b78 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotatedElementUtilsTests.java @@ -521,9 +521,9 @@ public class AnnotatedElementUtilsTests { Class element = InvalidConventionBasedComposedContextConfigClass.class; assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(() -> getMergedAnnotationAttributes(element, ContextConfig.class)) - .withMessageContaining("Different @AliasFor mirror values for annotation") - .withMessageContaining("attribute 'locations' and its alias 'value'") - .withMessageContaining("values of [{requiredLocationsDeclaration}] and [{duplicateDeclaration}]"); + .withMessageContaining("Different @AliasFor mirror values for annotation") + .withMessageContaining("attribute 'locations' and its alias 'value'") + .withMessageContaining("values of [{requiredLocationsDeclaration}] and [{duplicateDeclaration}]"); } @Test @@ -774,6 +774,12 @@ public class AnnotatedElementUtilsTests { assertThat(findMergedAnnotation(SpringAppConfigClass.class, Resource.class)).isEqualTo(SpringAppConfigClass.class.getAnnotation(Resource.class)); } + @Test + public void javaxMetaAnnotationTypeViaFindMergedAnnotation() throws Exception { + assertThat(findMergedAnnotation(ParametersAreNonnullByDefault.class, Nonnull.class)).isEqualTo(ParametersAreNonnullByDefault.class.getAnnotation(Nonnull.class)); + assertThat(findMergedAnnotation(ResourceHolder.class, Nonnull.class)).isEqualTo(ParametersAreNonnullByDefault.class.getAnnotation(Nonnull.class)); + } + @Test public void nullableAnnotationTypeViaFindMergedAnnotation() throws Exception { Method method = TransactionalServiceImpl.class.getMethod("doIt"); @@ -1375,6 +1381,7 @@ public class AnnotatedElementUtilsTests { } @Resource(name = "x") + @ParametersAreNonnullByDefault static class ResourceHolder { } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeCode.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeCode.java index 8a252f9309..aabc43d0b2 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeCode.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeCode.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. @@ -84,10 +84,9 @@ public enum TypeCode { public static TypeCode forName(String name) { - String searchingFor = name.toUpperCase(); TypeCode[] tcs = values(); for (int i = 1; i < tcs.length; i++) { - if (tcs[i].name().equals(searchingFor)) { + if (tcs[i].name().equalsIgnoreCase(name)) { return tcs[i]; } } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index a78cae7c59..7823d59c46 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.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. @@ -41,6 +41,7 @@ import org.springframework.expression.spel.CodeFlow; import org.springframework.expression.spel.CompilablePropertyAccessor; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -413,7 +414,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { method.getParameterCount() == numberOfParams && (!mustBeStatic || Modifier.isStatic(method.getModifiers())) && (requiredReturnTypes.isEmpty() || requiredReturnTypes.contains(method.getReturnType()))) { - return method; + return ClassUtils.getInterfaceMethodIfPossible(method); } } } diff --git a/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java b/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java index 049e5be287..80954b6878 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/SimpleJmsHeaderMapper.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. diff --git a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java index ba27b97937..9a20524958 100644 --- a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.java +++ b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultContextCache.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. diff --git a/spring-test/src/main/java/org/springframework/test/web/ModelAndViewAssert.java b/spring-test/src/main/java/org/springframework/test/web/ModelAndViewAssert.java index e7456f3f9a..f3415671bf 100644 --- a/spring-test/src/main/java/org/springframework/test/web/ModelAndViewAssert.java +++ b/spring-test/src/main/java/org/springframework/test/web/ModelAndViewAssert.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. @@ -142,7 +142,7 @@ public abstract class ModelAndViewAssert { * @param comparator the comparator to use (may be {@code null}). If not * specifying the comparator, both lists will be sorted not using any comparator. */ - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public static void assertSortAndCompareListModelAttribute( ModelAndView mav, String modelName, List expectedList, Comparator comparator) { diff --git a/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java index 6b7208bc3c..f6ec22df6e 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java +++ b/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.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. @@ -23,11 +23,10 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArrayList; import org.springframework.http.MediaType; import org.springframework.lang.Nullable; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; /** * An implementation of {@code MediaTypeFileExtensionResolver} that maintains @@ -37,15 +36,16 @@ import org.springframework.util.MultiValueMap; * Subsequently subclasses can use {@link #addMapping} to add more mappings. * * @author Rossen Stoyanchev + * @author Juergen Hoeller * @since 3.2 */ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExtensionResolver { private final ConcurrentMap mediaTypes = new ConcurrentHashMap<>(64); - private final MultiValueMap fileExtensions = new LinkedMultiValueMap<>(); + private final ConcurrentMap> fileExtensions = new ConcurrentHashMap<>(64); - private final List allFileExtensions = new ArrayList<>(); + private final List allFileExtensions = new CopyOnWriteArrayList<>(); /** @@ -53,12 +53,14 @@ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExten */ public MappingMediaTypeFileExtensionResolver(@Nullable Map mediaTypes) { if (mediaTypes != null) { + List allFileExtensions = new ArrayList<>(); mediaTypes.forEach((extension, mediaType) -> { String lowerCaseExtension = extension.toLowerCase(Locale.ENGLISH); this.mediaTypes.put(lowerCaseExtension, mediaType); - this.fileExtensions.add(mediaType, lowerCaseExtension); - this.allFileExtensions.add(lowerCaseExtension); + addFileExtension(mediaType, extension); + allFileExtensions.add(lowerCaseExtension); }); + this.allFileExtensions.addAll(allFileExtensions); } } @@ -77,11 +79,17 @@ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExten protected void addMapping(String extension, MediaType mediaType) { MediaType previous = this.mediaTypes.putIfAbsent(extension, mediaType); if (previous == null) { - this.fileExtensions.add(mediaType, extension); + addFileExtension(mediaType, extension); this.allFileExtensions.add(extension); } } + private void addFileExtension(MediaType mediaType, String extension) { + List newList = new CopyOnWriteArrayList<>(); + List oldList = this.fileExtensions.putIfAbsent(mediaType, newList); + (oldList != null ? oldList : newList).add(extension); + } + @Override public List resolveFileExtensions(MediaType mediaType) { diff --git a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java index 09df60896e..bf20dc472e 100644 --- a/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.java +++ b/spring-web/src/main/java/org/springframework/web/context/request/async/WebAsyncManager.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. @@ -253,7 +253,7 @@ public final class WebAsyncManager { * @see #getConcurrentResult() * @see #getConcurrentResultContext() */ - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public void startCallableProcessing(Callable callable, Object... processingContext) throws Exception { Assert.notNull(callable, "Callable must not be null"); startCallableProcessing(new WebAsyncTask(callable), processingContext); diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java b/spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java index 4b86022bde..fa5cfc4677 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java @@ -61,7 +61,7 @@ public class MapMethodProcessor implements HandlerMethodArgumentResolver, Handle } @Override - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({"rawtypes", "unchecked"}) public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributesHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributesHandler.java index debbc0fd74..9acbe85ec0 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributesHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/SessionAttributesHandler.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.