Merge branch '6.1.x'
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
@@ -29,7 +29,7 @@ import org.springframework.context.ApplicationEvent;
|
||||
public abstract class ApplicationContextEvent extends ApplicationEvent {
|
||||
|
||||
/**
|
||||
* Create a new ContextStartedEvent.
|
||||
* Create a new {@code ApplicationContextEvent}.
|
||||
* @param source the {@code ApplicationContext} that the event is raised for
|
||||
* (must not be {@code null})
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
@@ -29,7 +29,7 @@ import org.springframework.context.ApplicationContext;
|
||||
public class ContextClosedEvent extends ApplicationContextEvent {
|
||||
|
||||
/**
|
||||
* Creates a new ContextClosedEvent.
|
||||
* Create a new {@code ContextClosedEvent}.
|
||||
* @param source the {@code ApplicationContext} that has been closed
|
||||
* (must not be {@code null})
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
@@ -29,7 +29,7 @@ import org.springframework.context.ApplicationContext;
|
||||
public class ContextRefreshedEvent extends ApplicationContextEvent {
|
||||
|
||||
/**
|
||||
* Create a new ContextRefreshedEvent.
|
||||
* Create a new {@code ContextRefreshedEvent}.
|
||||
* @param source the {@code ApplicationContext} that has been initialized
|
||||
* or refreshed (must not be {@code null})
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.context.ApplicationContext;
|
||||
public class ContextStartedEvent extends ApplicationContextEvent {
|
||||
|
||||
/**
|
||||
* Create a new ContextStartedEvent.
|
||||
* Create a new {@code ContextStartedEvent}.
|
||||
* @param source the {@code ApplicationContext} that has been started
|
||||
* (must not be {@code null})
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.context.ApplicationContext;
|
||||
public class ContextStoppedEvent extends ApplicationContextEvent {
|
||||
|
||||
/**
|
||||
* Create a new ContextStoppedEvent.
|
||||
* Create a new {@code ContextStoppedEvent}.
|
||||
* @param source the {@code ApplicationContext} that has been stopped
|
||||
* (must not be {@code null})
|
||||
*/
|
||||
|
||||
@@ -234,8 +234,8 @@ public class MethodValidationAdapter implements MethodValidator {
|
||||
|
||||
@Override
|
||||
public final MethodValidationResult validateArguments(
|
||||
Object target, Method method, @Nullable MethodParameter[] parameters, Object[] arguments,
|
||||
Class<?>[] groups) {
|
||||
Object target, Method method, @Nullable MethodParameter[] parameters,
|
||||
Object[] arguments, Class<?>[] groups) {
|
||||
|
||||
Set<ConstraintViolation<Object>> violations =
|
||||
invokeValidatorForArguments(target, method, arguments, groups);
|
||||
@@ -256,23 +256,21 @@ public class MethodValidationAdapter implements MethodValidator {
|
||||
Object target, Method method, Object[] arguments, Class<?>[] groups) {
|
||||
|
||||
ExecutableValidator execVal = this.validator.get().forExecutables();
|
||||
Set<ConstraintViolation<Object>> violations;
|
||||
try {
|
||||
violations = execVal.validateParameters(target, method, arguments, groups);
|
||||
return execVal.validateParameters(target, method, arguments, groups);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011
|
||||
// Let's try to find the bridged method on the implementation class...
|
||||
Method bridgedMethod = BridgeMethodResolver.getMostSpecificMethod(method, target.getClass());
|
||||
violations = execVal.validateParameters(target, bridgedMethod, arguments, groups);
|
||||
return execVal.validateParameters(target, bridgedMethod, arguments, groups);
|
||||
}
|
||||
return violations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MethodValidationResult validateReturnValue(
|
||||
Object target, Method method, @Nullable MethodParameter returnType, @Nullable Object returnValue,
|
||||
Class<?>[] groups) {
|
||||
Object target, Method method, @Nullable MethodParameter returnType,
|
||||
@Nullable Object returnValue, Class<?>[] groups) {
|
||||
|
||||
Set<ConstraintViolation<Object>> violations =
|
||||
invokeValidatorForReturnValue(target, method, returnValue, groups);
|
||||
@@ -305,9 +303,9 @@ public class MethodValidationAdapter implements MethodValidator {
|
||||
Map<Path.Node, ParamErrorsBuilder> nestedViolations = new LinkedHashMap<>();
|
||||
|
||||
for (ConstraintViolation<Object> violation : violations) {
|
||||
Iterator<Path.Node> itr = violation.getPropertyPath().iterator();
|
||||
while (itr.hasNext()) {
|
||||
Path.Node node = itr.next();
|
||||
Iterator<Path.Node> nodes = violation.getPropertyPath().iterator();
|
||||
while (nodes.hasNext()) {
|
||||
Path.Node node = nodes.next();
|
||||
|
||||
MethodParameter parameter;
|
||||
if (node.getKind().equals(ElementKind.PARAMETER)) {
|
||||
@@ -328,8 +326,8 @@ public class MethodValidationAdapter implements MethodValidator {
|
||||
// https://github.com/jakartaee/validation/issues/194
|
||||
|
||||
Path.Node parameterNode = node;
|
||||
if (itr.hasNext()) {
|
||||
node = itr.next();
|
||||
if (nodes.hasNext()) {
|
||||
node = nodes.next();
|
||||
}
|
||||
|
||||
Object value;
|
||||
@@ -425,7 +423,6 @@ public class MethodValidationAdapter implements MethodValidator {
|
||||
* @return the name to use
|
||||
*/
|
||||
String resolveName(MethodParameter parameter, @Nullable Object value);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -456,6 +453,7 @@ public class MethodValidationAdapter implements MethodValidator {
|
||||
public ParamValidationResultBuilder(
|
||||
Object target, MethodParameter parameter, @Nullable Object value, @Nullable Object container,
|
||||
@Nullable Integer containerIndex, @Nullable Object containerKey) {
|
||||
|
||||
this.target = target;
|
||||
this.parameter = parameter;
|
||||
this.value = value;
|
||||
@@ -473,7 +471,6 @@ public class MethodValidationAdapter implements MethodValidator {
|
||||
this.parameter, this.value, this.resolvableErrors, this.container,
|
||||
this.containerIndex, this.containerKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -527,8 +524,7 @@ public class MethodValidationAdapter implements MethodValidator {
|
||||
|
||||
|
||||
/**
|
||||
* Default algorithm to select an object name, as described in
|
||||
* {@link #setObjectNameResolver(ObjectNameResolver)}.
|
||||
* Default algorithm to select an object name, as described in {@link #setObjectNameResolver}.
|
||||
*/
|
||||
private static class DefaultObjectNameResolver implements ObjectNameResolver {
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import jakarta.inject.Provider;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -43,6 +44,7 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -183,6 +185,14 @@ class AutowiredConfigurationTests {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValueInjectionWithAccidentalAutowiredAnnotations() {
|
||||
AnnotationConfigApplicationContext context =
|
||||
new AnnotationConfigApplicationContext(ValueConfigWithAccidentalAutowiredAnnotations.class);
|
||||
doTestValueInjection(context);
|
||||
context.close();
|
||||
}
|
||||
|
||||
private void doTestValueInjection(BeanFactory context) {
|
||||
System.clearProperty("myProp");
|
||||
|
||||
@@ -494,6 +504,32 @@ class AutowiredConfigurationTests {
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class ValueConfigWithAccidentalAutowiredAnnotations implements InitializingBean {
|
||||
|
||||
boolean invoked;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.state(!invoked, "Factory method must not get invoked on startup");
|
||||
}
|
||||
|
||||
@Bean @Scope("prototype")
|
||||
@Autowired
|
||||
public TestBean testBean(@Value("#{systemProperties[myProp]}") Provider<String> name) {
|
||||
invoked = true;
|
||||
return new TestBean(name.get());
|
||||
}
|
||||
|
||||
@Bean @Scope("prototype")
|
||||
@Autowired
|
||||
public TestBean testBean2(@Value("#{systemProperties[myProp]}") Provider<String> name2) {
|
||||
invoked = true;
|
||||
return new TestBean(name2.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class PropertiesConfig {
|
||||
|
||||
|
||||
@@ -276,8 +276,13 @@ public final class BridgeMethodResolver {
|
||||
*/
|
||||
public static boolean isVisibilityBridgeMethodPair(Method bridgeMethod, Method bridgedMethod) {
|
||||
if (bridgeMethod == bridgedMethod) {
|
||||
// Same method: for common purposes, return true to proceed as if it was a visibility bridge.
|
||||
return true;
|
||||
}
|
||||
if (ClassUtils.getUserClass(bridgeMethod.getDeclaringClass()) != bridgeMethod.getDeclaringClass()) {
|
||||
// Method on generated subclass: return false to consistently ignore it for visibility purposes.
|
||||
return false;
|
||||
}
|
||||
return (bridgeMethod.getReturnType().equals(bridgedMethod.getReturnType()) &&
|
||||
bridgeMethod.getParameterCount() == bridgedMethod.getParameterCount() &&
|
||||
Arrays.equals(bridgeMethod.getParameterTypes(), bridgedMethod.getParameterTypes()));
|
||||
|
||||
Reference in New Issue
Block a user