提交 bd70f10d 编写于 作者: J Juergen Hoeller

Merge branch '5.1.x'

# Conflicts:
#	build.gradle
#	spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java
#	spring-aspects/spring-aspects.gradle
#	spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
#	spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java
#	spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
#	spring-orm/spring-orm.gradle
#	spring-test/spring-test.gradle
......@@ -140,14 +140,14 @@ configure(allprojects) { project ->
dependency "org.webjars:webjars-locator-core:0.37"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.24') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.26') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
}
}
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.22') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.26') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
......@@ -344,7 +344,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.23"
toolVersion = "8.24"
configDir = rootProject.file("src/checkstyle")
}
......
......@@ -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;
......
......@@ -27,6 +27,7 @@ import org.springframework.util.PatternMatchUtils;
/**
* Pointcut bean for simple method name matches, as an alternative to regexp patterns.
*
* <p>Does not handle overloaded methods: all methods with a given name will be eligible.
*
* @author Juergen Hoeller
......
......@@ -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.
*
* <p>These methods are particularly useful for composing pointcuts
* using the union and intersection methods.
*
......
......@@ -20,7 +20,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") // for JCache aspect
optional("javax.cache:cache-api") // for JCache aspect
optional("javax.transaction:javax.transaction-api") // for @javax.transaction.Transactional support
testCompile(project(":spring-core")) // for CodeStyleAspect
testCompile(project(":spring-test"))
......
......@@ -256,7 +256,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)) {
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
......@@ -268,7 +268,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) {
......
......@@ -408,7 +408,7 @@ public class ConstructorArgumentValues {
for (Map.Entry<Integer, ValueHolder> 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;
}
}
......
......@@ -181,8 +181,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
@Nullable
private MutablePropertyValues propertyValues;
@Nullable
private MethodOverrides methodOverrides;
private MethodOverrides methodOverrides = new MethodOverrides();
@Nullable
private String initMethodName;
......@@ -903,9 +902,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* <p>Never returns {@code null}.
*/
public MethodOverrides getMethodOverrides() {
if (this.methodOverrides == null) {
this.methodOverrides = new MethodOverrides();
}
return this.methodOverrides;
}
......@@ -914,7 +910,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();
}
/**
......@@ -1098,10 +1094,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();
}
......@@ -1113,14 +1108,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<MethodOverride> overrides = getMethodOverrides().getOverrides();
synchronized (overrides) {
for (MethodOverride mo : overrides) {
prepareMethodOverride(mo);
}
}
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
......
......@@ -201,7 +201,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;
......
......@@ -325,7 +325,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);
}
......
/*
* 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(@Nullable 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
......
/*
* 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<MethodOverride> overrides = Collections.synchronizedSet(new LinkedHashSet<>(2));
private volatile boolean modified = false;
private final Set<MethodOverride> 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<MethodOverride> 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
......
......@@ -856,6 +856,18 @@ class DefaultListableBeanFactoryTests {
lbf.registerAlias("test", "test3");
}
@Test
void aliasChaining() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
lbf.registerAlias("test", "testAlias");
lbf.registerAlias("testAlias", "testAlias2");
lbf.registerAlias("testAlias2", "testAlias3");
Object bean = lbf.getBean("test");
assertThat(lbf.getBean("testAlias")).isSameAs(bean);
assertThat(lbf.getBean("testAlias2")).isSameAs(bean);
assertThat(lbf.getBean("testAlias3")).isSameAs(bean);
}
@Test
void beanDefinitionOverriding() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
......@@ -866,6 +878,43 @@ class DefaultListableBeanFactoryTests {
assertThat(lbf.getBean("test2")).isInstanceOf(NestedTestBean.class);
}
@Test
void beanDefinitionOverridingNotAllowed() {
lbf.setAllowBeanDefinitionOverriding(false);
BeanDefinition oldDef = new RootBeanDefinition(TestBean.class);
BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class);
lbf.registerBeanDefinition("test", oldDef);
assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() ->
lbf.registerBeanDefinition("test", newDef))
.satisfies(ex -> {
assertThat(ex.getBeanName()).isEqualTo("test");
assertThat(ex.getBeanDefinition()).isEqualTo(newDef);
assertThat(ex.getExistingDefinition()).isEqualTo(oldDef);
});
}
@Test
void beanDefinitionOverridingWithAlias() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
lbf.registerAlias("test", "testAlias");
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
lbf.registerAlias("test", "testAlias");
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
assertThat(lbf.getBean("testAlias")).isInstanceOf(NestedTestBean.class);
}
@Test
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);
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
assertThat(lbf.getBean("test", NestedTestBean.class).getCompany()).isEqualTo("value0");
}
@Test
void beanDefinitionRemoval() {
lbf.setAllowBeanDefinitionOverriding(false);
......@@ -908,43 +957,6 @@ class DefaultListableBeanFactoryTests {
lbf.removeBeanDefinition(name);
}
@Test
void beanDefinitionOverridingNotAllowed() {
lbf.setAllowBeanDefinitionOverriding(false);
BeanDefinition oldDef = new RootBeanDefinition(TestBean.class);
BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class);
lbf.registerBeanDefinition("test", oldDef);
assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() ->
lbf.registerBeanDefinition("test", newDef))
.satisfies(ex -> {
assertThat(ex.getBeanName()).isEqualTo("test");
assertThat(ex.getBeanDefinition()).isEqualTo(newDef);
assertThat(ex.getExistingDefinition()).isEqualTo(oldDef);
});
}
@Test
void beanDefinitionOverridingWithAlias() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
lbf.registerAlias("test", "testAlias");
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
lbf.registerAlias("test", "testAlias");
assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class);
assertThat(lbf.getBean("testAlias")).isInstanceOf(NestedTestBean.class);
}
@Test
void aliasChaining() {
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
lbf.registerAlias("test", "testAlias");
lbf.registerAlias("testAlias", "testAlias2");
lbf.registerAlias("testAlias2", "testAlias3");
Object bean = lbf.getBean("test");
assertThat(lbf.getBean("testAlias")).isSameAs(bean);
assertThat(lbf.getBean("testAlias2")).isSameAs(bean);
assertThat(lbf.getBean("testAlias3")).isSameAs(bean);
}
@Test
void beanReferenceWithNewSyntax() {
Properties p = new Properties();
......
......@@ -114,6 +114,27 @@ public class BeanDefinitionTests {
assertThat(bd.hashCode() == otherBd.hashCode()).isTrue();
}
@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);
......
......@@ -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
......
/*
* 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.
......
/*
* 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.
*
* <p>See <a href="package-summary.html">package-level javadocs</a> for more
* information on {@code org.springframework.asm}.
......
......@@ -980,8 +980,8 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> 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 {
......
......@@ -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())
......
/*
* 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));
* </pre>
*
* <p>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));
* </pre>
*
* <p>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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册