From 20fc7e178a82e366e4789cfe0152e40a38662813 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Sep 2019 12:07:29 +0200 Subject: [PATCH 1/6] Consistent equality check for parent name and indexed arguments Closes gh-23593 --- .../config/ConstructorArgumentValues.java | 4 +- .../support/GenericBeanDefinition.java | 12 ++- .../DefaultListableBeanFactoryTests.java | 90 +++++++++++-------- .../factory/support/BeanDefinitionTests.java | 23 ++++- 4 files changed, 85 insertions(+), 44 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java index c405d5c638d..40936a6fc26 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.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. @@ -408,7 +408,7 @@ public class ConstructorArgumentValues { for (Map.Entry entry : this.indexedArgumentValues.entrySet()) { ValueHolder vh1 = entry.getValue(); ValueHolder vh2 = that.indexedArgumentValues.get(entry.getKey()); - if (!vh1.contentEquals(vh2)) { + if (vh2 == null || !vh1.contentEquals(vh2)) { return false; } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java index 3a901e81674..c8f5ab4cb80 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.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. @@ -18,6 +18,7 @@ package org.springframework.beans.factory.support; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.lang.Nullable; +import org.springframework.util.ObjectUtils; /** * GenericBeanDefinition is a one-stop shop for standard bean definition purposes. @@ -84,7 +85,14 @@ public class GenericBeanDefinition extends AbstractBeanDefinition { @Override public boolean equals(Object other) { - return (this == other || (other instanceof GenericBeanDefinition && super.equals(other))); + if (this == other) { + return true; + } + if (!(other instanceof GenericBeanDefinition)) { + return false; + } + GenericBeanDefinition that = (GenericBeanDefinition) other; + return (ObjectUtils.nullSafeEquals(this.parentName, that.parentName) && super.equals(other)); } @Override diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index 9f27a5f7899..374064f315d 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -794,6 +794,18 @@ public class DefaultListableBeanFactoryTests { lbf.registerAlias("test", "test3"); } + @Test + public void testAliasChaining() { + lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class)); + lbf.registerAlias("test", "testAlias"); + lbf.registerAlias("testAlias", "testAlias2"); + lbf.registerAlias("testAlias2", "testAlias3"); + Object bean = lbf.getBean("test"); + assertSame(bean, lbf.getBean("testAlias")); + assertSame(bean, lbf.getBean("testAlias2")); + assertSame(bean, lbf.getBean("testAlias3")); + } + @Test public void testBeanDefinitionOverriding() { lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class)); @@ -804,6 +816,45 @@ public class DefaultListableBeanFactoryTests { assertTrue(lbf.getBean("test2") instanceof NestedTestBean); } + @Test + public void testBeanDefinitionOverridingNotAllowed() { + lbf.setAllowBeanDefinitionOverriding(false); + BeanDefinition oldDef = new RootBeanDefinition(TestBean.class); + BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class); + lbf.registerBeanDefinition("test", oldDef); + try { + lbf.registerBeanDefinition("test", newDef); + fail("Should have thrown BeanDefinitionOverrideException"); + } + catch (BeanDefinitionOverrideException ex) { + assertEquals("test", ex.getBeanName()); + assertSame(newDef, ex.getBeanDefinition()); + assertSame(oldDef, ex.getExistingDefinition()); + } + } + + @Test + public void testBeanDefinitionOverridingWithAlias() { + lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class)); + lbf.registerAlias("test", "testAlias"); + lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class)); + lbf.registerAlias("test", "testAlias"); + assertTrue(lbf.getBean("test") instanceof NestedTestBean); + assertTrue(lbf.getBean("testAlias") instanceof NestedTestBean); + } + + @Test + public void beanDefinitionOverridingWithConstructorArgumentMismatch() { + RootBeanDefinition bd1 = new RootBeanDefinition(NestedTestBean.class); + bd1.getConstructorArgumentValues().addIndexedArgumentValue(1, "value1"); + lbf.registerBeanDefinition("test", bd1); + RootBeanDefinition bd2 = new RootBeanDefinition(NestedTestBean.class); + bd2.getConstructorArgumentValues().addIndexedArgumentValue(0, "value0"); + lbf.registerBeanDefinition("test", bd2); + assertTrue(lbf.getBean("test") instanceof NestedTestBean); + assertEquals("value0", lbf.getBean("test", NestedTestBean.class).getCompany()); + } + @Test public void testBeanDefinitionRemoval() { lbf.setAllowBeanDefinitionOverriding(false); @@ -844,45 +895,6 @@ public class DefaultListableBeanFactoryTests { lbf.removeBeanDefinition(name); } - @Test - public void testBeanDefinitionOverridingNotAllowed() { - lbf.setAllowBeanDefinitionOverriding(false); - BeanDefinition oldDef = new RootBeanDefinition(TestBean.class); - BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class); - lbf.registerBeanDefinition("test", oldDef); - try { - lbf.registerBeanDefinition("test", newDef); - fail("Should have thrown BeanDefinitionOverrideException"); - } - catch (BeanDefinitionOverrideException ex) { - assertEquals("test", ex.getBeanName()); - assertSame(newDef, ex.getBeanDefinition()); - assertSame(oldDef, ex.getExistingDefinition()); - } - } - - @Test - public void testBeanDefinitionOverridingWithAlias() { - lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class)); - lbf.registerAlias("test", "testAlias"); - lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class)); - lbf.registerAlias("test", "testAlias"); - assertTrue(lbf.getBean("test") instanceof NestedTestBean); - assertTrue(lbf.getBean("testAlias") instanceof NestedTestBean); - } - - @Test - public void testAliasChaining() { - lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class)); - lbf.registerAlias("test", "testAlias"); - lbf.registerAlias("testAlias", "testAlias2"); - lbf.registerAlias("testAlias2", "testAlias3"); - Object bean = lbf.getBean("test"); - assertSame(bean, lbf.getBean("testAlias")); - assertSame(bean, lbf.getBean("testAlias2")); - assertSame(bean, lbf.getBean("testAlias3")); - } - @Test public void testBeanReferenceWithNewSyntax() { Properties p = new Properties(); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionTests.java index a2df91991b3..34a8a85a7fb 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/support/BeanDefinitionTests.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. @@ -100,6 +100,27 @@ public class BeanDefinitionTests { assertTrue(bd.hashCode() == otherBd.hashCode()); } + @Test + public void genericBeanDefinitionEquality() { + GenericBeanDefinition bd = new GenericBeanDefinition(); + bd.setParentName("parent"); + bd.setScope("request"); + bd.setAbstract(true); + bd.setLazyInit(true); + GenericBeanDefinition otherBd = new GenericBeanDefinition(); + otherBd.setScope("request"); + otherBd.setAbstract(true); + otherBd.setLazyInit(true); + boolean condition1 = !bd.equals(otherBd); + assertTrue(condition1); + boolean condition = !otherBd.equals(bd); + assertTrue(condition); + otherBd.setParentName("parent"); + assertTrue(bd.equals(otherBd)); + assertTrue(otherBd.equals(bd)); + assertTrue(bd.hashCode() == otherBd.hashCode()); + } + @Test public void beanDefinitionHolderEquality() { RootBeanDefinition bd = new RootBeanDefinition(TestBean.class); From da44a247cb08013c42f9bde70ee6a99e8eb7c62b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Sep 2019 12:09:16 +0200 Subject: [PATCH 2/6] Efficient concurrency in MethodOverrides through CopyOnWriteArraySet Also restores immediate MethodOverrides instance in AbstractBeanDefinition, avoiding potential lazy-init race condition. Closes gh-23448 --- .../support/AbstractBeanDefinition.java | 22 ++++---------- .../factory/support/MethodOverrides.java | 30 ++++++------------- 2 files changed, 15 insertions(+), 37 deletions(-) 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 4a10cdb1555..4fa941961a5 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 @@ -179,8 +179,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess @Nullable private MutablePropertyValues propertyValues; - @Nullable - private MethodOverrides methodOverrides; + private MethodOverrides methodOverrides = new MethodOverrides(); @Nullable private String initMethodName; @@ -869,9 +868,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess *

Never returns {@code null}. */ public MethodOverrides getMethodOverrides() { - if (this.methodOverrides == null) { - this.methodOverrides = new MethodOverrides(); - } return this.methodOverrides; } @@ -880,7 +876,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess * @since 5.0.2 */ public boolean hasMethodOverrides() { - return (this.methodOverrides != null && !this.methodOverrides.isEmpty()); + return !this.methodOverrides.isEmpty(); } /** @@ -1064,10 +1060,9 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess public void validate() throws BeanDefinitionValidationException { if (hasMethodOverrides() && getFactoryMethodName() != null) { throw new BeanDefinitionValidationException( - "Cannot combine static factory method with method overrides: " + - "the static factory method must create the instance"); + "Cannot combine factory method with container-generated method overrides: " + + "the factory method must create the concrete bean instance."); } - if (hasBeanClass()) { prepareMethodOverrides(); } @@ -1079,14 +1074,9 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess * @throws BeanDefinitionValidationException in case of validation failure */ public void prepareMethodOverrides() throws BeanDefinitionValidationException { - // Check that lookup methods exists. + // Check that lookup methods exist and determine their overloaded status. if (hasMethodOverrides()) { - Set overrides = getMethodOverrides().getOverrides(); - synchronized (overrides) { - for (MethodOverride mo : overrides) { - prepareMethodOverride(mo); - } - } + getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride); } } 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 50f507aaec4..937f3c0e039 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 @@ -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. @@ -17,9 +17,8 @@ package org.springframework.beans.factory.support; import java.lang.reflect.Method; -import java.util.Collections; -import java.util.LinkedHashSet; import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; import org.springframework.lang.Nullable; @@ -37,9 +36,7 @@ import org.springframework.lang.Nullable; */ public class MethodOverrides { - private final Set overrides = Collections.synchronizedSet(new LinkedHashSet<>(2)); - - private volatile boolean modified = false; + private final Set overrides = new CopyOnWriteArraySet<>(); /** @@ -61,7 +58,6 @@ public class MethodOverrides { */ public void addOverrides(@Nullable MethodOverrides other) { if (other != null) { - this.modified = true; this.overrides.addAll(other.overrides); } } @@ -70,7 +66,6 @@ public class MethodOverrides { * Add the given method override. */ public void addOverride(MethodOverride override) { - this.modified = true; this.overrides.add(override); } @@ -80,7 +75,6 @@ public class MethodOverrides { * @see MethodOverride */ public Set getOverrides() { - this.modified = true; return this.overrides; } @@ -88,7 +82,7 @@ public class MethodOverrides { * Return whether the set of method overrides is empty. */ public boolean isEmpty() { - return (!this.modified || this.overrides.isEmpty()); + return this.overrides.isEmpty(); } /** @@ -98,18 +92,13 @@ public class MethodOverrides { */ @Nullable public MethodOverride getOverride(Method method) { - if (!this.modified) { - return null; - } - synchronized (this.overrides) { - MethodOverride match = null; - for (MethodOverride candidate : this.overrides) { - if (candidate.matches(method)) { - match = candidate; - } + MethodOverride match = null; + for (MethodOverride candidate : this.overrides) { + if (candidate.matches(method)) { + match = candidate; } - return match; } + return match; } @@ -123,7 +112,6 @@ public class MethodOverrides { } MethodOverrides that = (MethodOverrides) other; return this.overrides.equals(that.overrides); - } @Override From 6a08bfdff75db1a8dfb9ab11d76df5a12bb183c4 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Sep 2019 12:10:23 +0200 Subject: [PATCH 3/6] Avoid unnecessary synchronization for non-existent missing caches Closes gh-23635 --- .../cache/support/AbstractCacheManager.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java b/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java index 50ab5ccb317..981200b5388 100644 --- a/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java @@ -87,25 +87,26 @@ public abstract class AbstractCacheManager implements CacheManager, Initializing @Override @Nullable public Cache getCache(String name) { + // Quick check for existing cache... Cache cache = this.cacheMap.get(name); if (cache != null) { return cache; } - else { - // Fully synchronize now for missing cache creation... + + // The provider may support on-demand cache creation... + Cache missingCache = getMissingCache(name); + if (missingCache != null) { + // Fully synchronize now for missing cache registration synchronized (this.cacheMap) { cache = this.cacheMap.get(name); if (cache == null) { - cache = getMissingCache(name); - if (cache != null) { - cache = decorateCache(cache); - this.cacheMap.put(name, cache); - updateCacheNames(name); - } + cache = decorateCache(missingCache); + this.cacheMap.put(name, cache); + updateCacheNames(name); } - return cache; } } + return cache; } @Override From 0519a2ff3c745f9898775745aaf83fcd67b2f1b5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Sep 2019 12:11:33 +0200 Subject: [PATCH 4/6] Exclude jdk package in ShadowingClassLoader (JDK 11 compatibility) Closes gh-23641 --- .../instrument/classloading/ShadowingClassLoader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/ShadowingClassLoader.java b/spring-context/src/main/java/org/springframework/instrument/classloading/ShadowingClassLoader.java index f8719640ab5..49869101d2c 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/ShadowingClassLoader.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/ShadowingClassLoader.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. @@ -48,7 +48,7 @@ public class ShadowingClassLoader extends DecoratingClassLoader { /** Packages that are excluded by default. */ public static final String[] DEFAULT_EXCLUDED_PACKAGES = - new String[] {"java.", "javax.", "sun.", "oracle.", "com.sun.", "com.ibm.", "COM.ibm.", + new String[] {"java.", "javax.", "jdk.", "sun.", "oracle.", "com.sun.", "com.ibm.", "COM.ibm.", "org.w3c.", "org.xml.", "org.dom4j.", "org.eclipse", "org.aspectj.", "net.sf.cglib", "org.springframework.cglib", "org.apache.xerces.", "org.apache.commons.logging."}; From bb6f9bb6d4b8cc447fa117d77287fa93d8e02c89 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Sep 2019 12:14:48 +0200 Subject: [PATCH 5/6] Polishing --- .../aop/framework/CglibAopProxy.java | 11 ++++++----- .../aop/framework/ReflectiveMethodInvocation.java | 6 +++--- .../aop/support/DefaultIntroductionAdvisor.java | 2 +- .../aop/support/NameMatchMethodPointcut.java | 1 + .../org/springframework/aop/support/Pointcuts.java | 1 + .../AutowiredAnnotationBeanPostProcessor.java | 14 ++++++++------ .../CglibSubclassingInstantiationStrategy.java | 2 +- .../support/DefaultListableBeanFactory.java | 3 ++- .../org/springframework/asm/SpringAsmInfo.java | 4 ++-- .../util/ConcurrentReferenceHashMap.java | 6 +++--- .../test/web/reactive/server/ExchangeResult.java | 8 ++------ .../servlet/mvc/method/annotation/SseEmitter.java | 10 +++------- 12 files changed, 33 insertions(+), 35 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index ab98557e291..b87aa3aabf5 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.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. @@ -327,10 +327,11 @@ class CglibAopProxy implements AopProxy, Serializable { // TODO: small memory optimization here (can skip creation for methods with no advice) for (int x = 0; x < methods.length; x++) { - List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass); + Method method = methods[x]; + List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass); fixedCallbacks[x] = new FixedChainStaticTargetInterceptor( chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass()); - this.fixedInterceptorMap.put(methods[x].toString(), x); + this.fixedInterceptorMap.put(methods.toString(), x); } // Now copy both the callbacks from mainCallbacks @@ -633,8 +634,8 @@ class CglibAopProxy implements AopProxy, Serializable { @Override @Nullable public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { - MethodInvocation invocation = new CglibMethodInvocation(proxy, this.target, method, args, - this.targetClass, this.adviceChain, methodProxy); + MethodInvocation invocation = new CglibMethodInvocation( + proxy, this.target, method, args, this.targetClass, this.adviceChain, methodProxy); // If we get here, we need to create a MethodInvocation. Object retVal = invocation.proceed(); retVal = processReturnType(proxy, this.target, method, retVal); diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java b/spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java index e365bd2bba3..0eef701a932 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.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. @@ -68,7 +68,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea protected final Method method; - protected Object[] arguments = new Object[0]; + protected Object[] arguments; @Nullable private final Class targetClass; @@ -158,7 +158,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea @Override @Nullable public Object proceed() throws Throwable { - // We start with an index of -1 and increment early. + // We start with an index of -1 and increment early. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java index 2dab972470e..1c65a19a2ae 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/DefaultIntroductionAdvisor.java @@ -39,7 +39,7 @@ import org.springframework.util.ClassUtils; * @author Juergen Hoeller * @since 11.11.2003 */ -@SuppressWarnings({"serial" }) +@SuppressWarnings("serial") public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFilter, Ordered, Serializable { private final Advice advice; diff --git a/spring-aop/src/main/java/org/springframework/aop/support/NameMatchMethodPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/NameMatchMethodPointcut.java index 1509a1eb6ca..c2c86b5be4e 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/NameMatchMethodPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/NameMatchMethodPointcut.java @@ -26,6 +26,7 @@ import org.springframework.util.PatternMatchUtils; /** * Pointcut bean for simple method name matches, as an alternative to regexp patterns. + * *

Does not handle overloaded methods: all methods with a given name will be eligible. * * @author Juergen Hoeller diff --git a/spring-aop/src/main/java/org/springframework/aop/support/Pointcuts.java b/spring-aop/src/main/java/org/springframework/aop/support/Pointcuts.java index 39c7e8c0ed2..7e2ac454dfd 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/Pointcuts.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/Pointcuts.java @@ -26,6 +26,7 @@ import org.springframework.util.Assert; /** * Pointcut constants for matching getters and setters, * and static methods useful for manipulating and evaluating pointcuts. + * *

These methods are particularly useful for composing pointcuts * using the union and intersection methods. * diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 5b934e5587a..53d36462bb5 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.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. @@ -139,9 +139,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean /** - * Create a new AutowiredAnnotationBeanPostProcessor - * for Spring's standard {@link Autowired} annotation. - *

Also supports JSR-330's {@link javax.inject.Inject} annotation, if available. + * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's + * standard {@link Autowired @Autowired} annotation. + *

Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation, + * if available. */ @SuppressWarnings("unchecked") public AutowiredAnnotationBeanPostProcessor() { @@ -242,7 +243,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean public Constructor[] determineCandidateConstructors(Class beanClass, final String beanName) throws BeanCreationException { - // Let's check for lookup methods here.. + // Let's check for lookup methods here... if (!this.lookupMethodsChecked.contains(beanName)) { try { ReflectionUtils.doWithMethods(beanClass, method -> { @@ -251,7 +252,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean Assert.state(this.beanFactory != null, "No BeanFactory available"); LookupOverride override = new LookupOverride(method, lookup.value()); try { - RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName); + RootBeanDefinition mbd = (RootBeanDefinition) + this.beanFactory.getMergedBeanDefinition(beanName); mbd.getMethodOverrides().addOverride(override); } catch (NoSuchBeanDefinitionException ex) { 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 60e8a116728..d46561af8b6 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 @@ -249,7 +249,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt public int accept(Method method) { MethodOverride methodOverride = getBeanDefinition().getMethodOverrides().getOverride(method); if (logger.isTraceEnabled()) { - logger.trace("Override for '" + method.getName() + "' is [" + methodOverride + "]"); + logger.trace("MethodOverride for " + method + ": " + methodOverride); } if (methodOverride == null) { return PASSTHROUGH; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 57bea2020d5..4e05ecf5f33 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -322,7 +322,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading; this.dependencyComparator = otherListableFactory.dependencyComparator; // A clone of the AutowireCandidateResolver since it is potentially BeanFactoryAware... - setAutowireCandidateResolver(BeanUtils.instantiateClass(otherListableFactory.getAutowireCandidateResolver().getClass())); + setAutowireCandidateResolver( + BeanUtils.instantiateClass(otherListableFactory.getAutowireCandidateResolver().getClass())); // Make resolvable dependencies (e.g. ResourceLoader) available here as well... this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies); } diff --git a/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java b/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java index 745a1ecec66..d74833951db 100644 --- a/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.java +++ b/spring-core/src/main/java/org/springframework/asm/SpringAsmInfo.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. @@ -18,7 +18,7 @@ package org.springframework.asm; /** * Utility class exposing constants related to Spring's internal repackaging - * of the ASM bytecode library: currently based on ASM 7.0 plus minor patches. + * of the ASM bytecode library: currently based on ASM 7.x plus minor patches. * *

See package-level javadocs for more * information on {@code org.springframework.asm}. diff --git a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java index a650f68baa5..7e8f06696f5 100644 --- a/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java +++ b/spring-core/src/main/java/org/springframework/util/ConcurrentReferenceHashMap.java @@ -829,7 +829,7 @@ public class ConcurrentReferenceHashMap extends AbstractMap implemen /** - * Allows a task access to {@link Segment} entries. + * Allows a task access to {@link ConcurrentReferenceHashMap.Segment} entries. */ private abstract class Entries { @@ -980,8 +980,8 @@ public class ConcurrentReferenceHashMap extends AbstractMap implemen /** - * Strategy class used to manage {@link Reference References}. This class can be overridden if - * alternative reference types need to be supported. + * Strategy class used to manage {@link Reference References}. + * This class can be overridden if alternative reference types need to be supported. */ protected class ReferenceManager { diff --git a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java index f94b49965ca..77e514dd757 100644 --- a/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/reactive/server/ExchangeResult.java @@ -155,7 +155,7 @@ public class ExchangeResult { /** - * Return the status of the executed request. + * Return the HTTP status code as an {@link HttpStatus} enum value. */ public HttpStatus getStatus() { return this.response.getStatusCode(); @@ -219,16 +219,12 @@ public class ExchangeResult { "\n" + formatBody(getRequestHeaders().getContentType(), this.requestBody) + "\n" + "\n" + - "< " + getStatus() + " " + getStatusReason() + "\n" + + "< " + getStatus() + " " + getStatus().getReasonPhrase() + "\n" + "< " + formatHeaders(getResponseHeaders(), "\n< ") + "\n" + "\n" + formatBody(getResponseHeaders().getContentType(), this.responseBody) +"\n"; } - private String getStatusReason() { - return getStatus().getReasonPhrase(); - } - private String formatHeaders(HttpHeaders headers, String delimiter) { return headers.entrySet().stream() .map(entry -> entry.getKey() + ": " + entry.getValue()) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java index e55d68285db..de636f2ad85 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.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. @@ -41,7 +41,7 @@ public class SseEmitter extends ResponseBodyEmitter { static final MediaType TEXT_PLAIN = new MediaType("text", "plain", StandardCharsets.UTF_8); - static final MediaType UTF8_TEXT_EVENTSTREAM = new MediaType("text", "event-stream", StandardCharsets.UTF_8); + static final MediaType TEXT_EVENTSTREAM = new MediaType("text", "event-stream", StandardCharsets.UTF_8); /** @@ -70,7 +70,7 @@ public class SseEmitter extends ResponseBodyEmitter { HttpHeaders headers = outputMessage.getHeaders(); if (headers.getContentType() == null) { - headers.setContentType(UTF8_TEXT_EVENTSTREAM); + headers.setContentType(TEXT_EVENTSTREAM); } } @@ -82,10 +82,8 @@ public class SseEmitter extends ResponseBodyEmitter { * SseEmitter emitter = new SseEmitter(); * emitter.send(event().data(myObject)); * - * *

Please, see {@link ResponseBodyEmitter#send(Object) parent Javadoc} * for important notes on exception handling. - * * @param object the object to write * @throws IOException raised when an I/O error occurs * @throws java.lang.IllegalStateException wraps any other errors @@ -103,10 +101,8 @@ public class SseEmitter extends ResponseBodyEmitter { * SseEmitter emitter = new SseEmitter(); * emitter.send(event().data(myObject, MediaType.APPLICATION_JSON)); * - * *

Please, see {@link ResponseBodyEmitter#send(Object) parent Javadoc} * for important notes on exception handling. - * * @param object the object to write * @param mediaType a MediaType hint for selecting an HttpMessageConverter * @throws IOException raised when an I/O error occurs From b1ed0511f7775c9edda3ea922cc8b7f6da3699dd Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Sep 2019 12:15:02 +0200 Subject: [PATCH 6/6] Upgrade to Tomcat 9.0.26, Undertow 2.0.26, Hibernate ORM 5.3.12 Includes Netty 4.1.39 (aligned with Reactor) and Checkstyle 8.24. --- build.gradle | 8 ++++---- spring-aspects/spring-aspects.gradle | 2 +- spring-orm/spring-orm.gradle | 2 +- spring-test/spring-test.gradle | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 0bb9c5d9c2a..438fb88bba2 100644 --- a/build.gradle +++ b/build.gradle @@ -37,15 +37,15 @@ ext { junit5Version = "5.3.2" kotlinVersion = "1.2.71" log4jVersion = "2.11.2" - nettyVersion = "4.1.38.Final" + nettyVersion = "4.1.39.Final" reactorVersion = "Californium-SR12" rxjavaVersion = "1.3.8" rxjavaAdapterVersion = "1.2.1" rxjava2Version = "2.2.10" slf4jVersion = "1.7.26" // spring-jcl + consistent 3rd party deps tiles3Version = "3.0.8" - tomcatVersion = "9.0.22" - undertowVersion = "2.0.23.Final" + tomcatVersion = "9.0.26" + undertowVersion = "2.0.26.Final" gradleScriptDir = "${rootProject.projectDir}/gradle" withoutJclOverSlf4j = { @@ -142,7 +142,7 @@ configure(allprojects) { project -> } checkstyle { - toolVersion = "8.23" + toolVersion = "8.24" configDir = rootProject.file("src/checkstyle") } diff --git a/spring-aspects/spring-aspects.gradle b/spring-aspects/spring-aspects.gradle index 51bab8a8198..0152c677a95 100644 --- a/spring-aspects/spring-aspects.gradle +++ b/spring-aspects/spring-aspects.gradle @@ -89,7 +89,7 @@ dependencies { optional(project(":spring-context-support")) // for JavaMail and JSR-107 support optional(project(":spring-orm")) // for JPA exception translation support optional(project(":spring-tx")) // for JPA, @Transactional support - optional("javax.cache:cache-api:1.1.0") // for JCache aspect + optional("javax.cache:cache-api:1.1.0") // for JCache aspect optional("javax.transaction:javax.transaction-api:1.3") // for @javax.transaction.Transactional support testCompile(project(":spring-core")) // for CodeStyleAspect testCompile(project(":spring-test")) diff --git a/spring-orm/spring-orm.gradle b/spring-orm/spring-orm.gradle index 037031e35ab..9fa89d919d3 100644 --- a/spring-orm/spring-orm.gradle +++ b/spring-orm/spring-orm.gradle @@ -9,7 +9,7 @@ dependencies { optional(project(":spring-context")) optional(project(":spring-web")) optional("org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.4") - optional("org.hibernate:hibernate-core:5.3.10.Final") + optional("org.hibernate:hibernate-core:5.3.12.Final") optional("javax.servlet:javax.servlet-api:3.1.0") testCompile("org.aspectj:aspectjweaver:${aspectjVersion}") testCompile("org.hsqldb:hsqldb:${hsqldbVersion}") diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle index 5d6507a2601..d4ecfbbe76a 100644 --- a/spring-test/spring-test.gradle +++ b/spring-test/spring-test.gradle @@ -60,7 +60,7 @@ dependencies { testCompile("javax.ejb:javax.ejb-api:3.2") testCompile("javax.interceptor:javax.interceptor-api:1.2.2") testCompile("javax.mail:javax.mail-api:1.6.2") - testCompile("org.hibernate:hibernate-core:5.3.10.Final") + testCompile("org.hibernate:hibernate-core:5.3.12.Final") testCompile("org.hibernate:hibernate-validator:6.0.17.Final") // Enable use of the JUnit Platform Runner testCompile("org.junit.platform:junit-platform-runner")