Browse Source

Merge branch '6.1.x'

pull/34537/head
Juergen Hoeller 2 years ago
parent
commit
d9ca263065
  1. 6
      spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBeanRuntimeHints.java
  2. 12
      spring-context/src/main/java/org/springframework/context/aot/ReflectiveProcessorBeanFactoryInitializationAotProcessor.java
  3. 5
      spring-core/src/main/java/org/springframework/aot/hint/annotation/Reflective.java
  4. 4
      spring-core/src/main/java/org/springframework/aot/hint/annotation/RegisterReflectionForBinding.java
  5. 3
      spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java
  6. 88
      spring-orm/src/test/java/org/springframework/orm/jpa/SharedEntityManagerCreatorTests.java
  7. 2
      spring-web/src/main/java/org/springframework/web/client/NoOpResponseErrorHandler.java
  8. 3
      spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java

6
spring-context-support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBeanRuntimeHints.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,7 +37,7 @@ class SchedulerFactoryBeanRuntimeHints implements RuntimeHintsRegistrar {
private static final String SCHEDULER_FACTORY_CLASS_NAME = "org.quartz.impl.StdSchedulerFactory"; private static final String SCHEDULER_FACTORY_CLASS_NAME = "org.quartz.impl.StdSchedulerFactory";
private final ReflectiveRuntimeHintsRegistrar reflectiveRegistrar = new ReflectiveRuntimeHintsRegistrar(); private static final ReflectiveRuntimeHintsRegistrar registrar = new ReflectiveRuntimeHintsRegistrar();
@Override @Override
@ -49,7 +49,7 @@ class SchedulerFactoryBeanRuntimeHints implements RuntimeHintsRegistrar {
.registerType(TypeReference.of(SCHEDULER_FACTORY_CLASS_NAME), this::typeHint) .registerType(TypeReference.of(SCHEDULER_FACTORY_CLASS_NAME), this::typeHint)
.registerTypes(TypeReference.listOf(ResourceLoaderClassLoadHelper.class, .registerTypes(TypeReference.listOf(ResourceLoaderClassLoadHelper.class,
LocalTaskExecutorThreadPool.class, LocalDataSourceJobStore.class), this::typeHint); LocalTaskExecutorThreadPool.class, LocalDataSourceJobStore.class), this::typeHint);
this.reflectiveRegistrar.registerRuntimeHints(hints, LocalTaskExecutorThreadPool.class); registrar.registerRuntimeHints(hints, LocalTaskExecutorThreadPool.class);
} }
private void typeHint(Builder typeHint) { private void typeHint(Builder typeHint) {

12
spring-context/src/main/java/org/springframework/context/aot/ReflectiveProcessorBeanFactoryInitializationAotProcessor.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,7 +39,8 @@ import org.springframework.beans.factory.support.RegisteredBean;
*/ */
class ReflectiveProcessorBeanFactoryInitializationAotProcessor implements BeanFactoryInitializationAotProcessor { class ReflectiveProcessorBeanFactoryInitializationAotProcessor implements BeanFactoryInitializationAotProcessor {
private static final ReflectiveRuntimeHintsRegistrar REGISTRAR = new ReflectiveRuntimeHintsRegistrar(); private static final ReflectiveRuntimeHintsRegistrar registrar = new ReflectiveRuntimeHintsRegistrar();
@Override @Override
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) { public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
@ -49,7 +50,9 @@ class ReflectiveProcessorBeanFactoryInitializationAotProcessor implements BeanFa
return new ReflectiveProcessorBeanFactoryInitializationAotContribution(beanTypes); return new ReflectiveProcessorBeanFactoryInitializationAotContribution(beanTypes);
} }
private static class ReflectiveProcessorBeanFactoryInitializationAotContribution implements BeanFactoryInitializationAotContribution {
private static class ReflectiveProcessorBeanFactoryInitializationAotContribution
implements BeanFactoryInitializationAotContribution {
private final Class<?>[] types; private final Class<?>[] types;
@ -60,9 +63,8 @@ class ReflectiveProcessorBeanFactoryInitializationAotProcessor implements BeanFa
@Override @Override
public void applyTo(GenerationContext generationContext, BeanFactoryInitializationCode beanFactoryInitializationCode) { public void applyTo(GenerationContext generationContext, BeanFactoryInitializationCode beanFactoryInitializationCode) {
RuntimeHints runtimeHints = generationContext.getRuntimeHints(); RuntimeHints runtimeHints = generationContext.getRuntimeHints();
REGISTRAR.registerRuntimeHints(runtimeHints, this.types); registrar.registerRuntimeHints(runtimeHints, this.types);
} }
} }
} }

5
spring-core/src/main/java/org/springframework/aot/hint/annotation/Reflective.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,8 +39,7 @@ import org.springframework.core.annotation.AliasFor;
* @see ReflectiveRuntimeHintsRegistrar * @see ReflectiveRuntimeHintsRegistrar
* @see RegisterReflectionForBinding @RegisterReflectionForBinding * @see RegisterReflectionForBinding @RegisterReflectionForBinding
*/ */
@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.CONSTRUCTOR, @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD})
ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface Reflective { public @interface Reflective {

4
spring-core/src/main/java/org/springframework/aot/hint/annotation/RegisterReflectionForBinding.java

@ -36,7 +36,7 @@ import org.springframework.core.annotation.AliasFor;
* *
* <pre class="code"> * <pre class="code">
* &#064;Configuration * &#064;Configuration
* &#064;RegisterReflectionForBinding({ Foo.class, Bar.class }) * &#064;RegisterReflectionForBinding({Foo.class, Bar.class})
* public class MyConfig { * public class MyConfig {
* // ... * // ...
* }</pre> * }</pre>
@ -78,7 +78,7 @@ public @interface RegisterReflectionForBinding {
/** /**
* Classes for which reflection hints should be registered. * Classes for which reflection hints should be registered.
* <p>At least one class must be specified either via {@link #value} or * <p>At least one class must be specified either via {@link #value} or
* {@link #classes}. * {@code #classes}.
* @see #value() * @see #value()
*/ */
@AliasFor("value") @AliasFor("value")

3
spring-orm/src/main/java/org/springframework/orm/jpa/SharedEntityManagerCreator.java

@ -395,6 +395,9 @@ public abstract class SharedEntityManagerCreator {
else if (targetClass.isInstance(proxy)) { else if (targetClass.isInstance(proxy)) {
return proxy; return proxy;
} }
else {
return this.target.unwrap(targetClass);
}
} }
case "getOutputParameterValue" -> { case "getOutputParameterValue" -> {
if (this.entityManager == null) { if (this.entityManager == null) {

88
spring-orm/src/test/java/org/springframework/orm/jpa/SharedEntityManagerCreatorTests.java

@ -105,15 +105,20 @@ class SharedEntityManagerCreatorTests {
void deferredQueryWithUpdate() { void deferredQueryWithUpdate() {
EntityManagerFactory emf = mock(); EntityManagerFactory emf = mock();
EntityManager targetEm = mock(); EntityManager targetEm = mock();
Query query = mock(); Query targetQuery = mock();
given(emf.createEntityManager()).willReturn(targetEm); given(emf.createEntityManager()).willReturn(targetEm);
given(targetEm.createQuery("x")).willReturn(query); given(targetEm.createQuery("x")).willReturn(targetQuery);
given(targetEm.isOpen()).willReturn(true); given(targetEm.isOpen()).willReturn(true);
given((Query) targetQuery.unwrap(targetQuery.getClass())).willReturn(targetQuery);
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf); EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
em.createQuery("x").executeUpdate(); Query query = em.createQuery("x");
assertThat((Query) query.unwrap(null)).isSameAs(targetQuery);
assertThat((Query) query.unwrap(targetQuery.getClass())).isSameAs(targetQuery);
assertThat(query.unwrap(Query.class)).isSameAs(query);
query.executeUpdate();
verify(query).executeUpdate(); verify(targetQuery).executeUpdate();
verify(targetEm).close(); verify(targetEm).close();
} }
@ -121,15 +126,20 @@ class SharedEntityManagerCreatorTests {
void deferredQueryWithSingleResult() { void deferredQueryWithSingleResult() {
EntityManagerFactory emf = mock(); EntityManagerFactory emf = mock();
EntityManager targetEm = mock(); EntityManager targetEm = mock();
Query query = mock(); Query targetQuery = mock();
given(emf.createEntityManager()).willReturn(targetEm); given(emf.createEntityManager()).willReturn(targetEm);
given(targetEm.createQuery("x")).willReturn(query); given(targetEm.createQuery("x")).willReturn(targetQuery);
given(targetEm.isOpen()).willReturn(true); given(targetEm.isOpen()).willReturn(true);
given((Query) targetQuery.unwrap(targetQuery.getClass())).willReturn(targetQuery);
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf); EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
em.createQuery("x").getSingleResult(); Query query = em.createQuery("x");
assertThat((Query) query.unwrap(null)).isSameAs(targetQuery);
assertThat((Query) query.unwrap(targetQuery.getClass())).isSameAs(targetQuery);
assertThat(query.unwrap(Query.class)).isSameAs(query);
query.getSingleResult();
verify(query).getSingleResult(); verify(targetQuery).getSingleResult();
verify(targetEm).close(); verify(targetEm).close();
} }
@ -137,15 +147,20 @@ class SharedEntityManagerCreatorTests {
void deferredQueryWithResultList() { void deferredQueryWithResultList() {
EntityManagerFactory emf = mock(); EntityManagerFactory emf = mock();
EntityManager targetEm = mock(); EntityManager targetEm = mock();
Query query = mock(); Query targetQuery = mock();
given(emf.createEntityManager()).willReturn(targetEm); given(emf.createEntityManager()).willReturn(targetEm);
given(targetEm.createQuery("x")).willReturn(query); given(targetEm.createQuery("x")).willReturn(targetQuery);
given(targetEm.isOpen()).willReturn(true); given(targetEm.isOpen()).willReturn(true);
given((Query) targetQuery.unwrap(targetQuery.getClass())).willReturn(targetQuery);
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf); EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
em.createQuery("x").getResultList(); Query query = em.createQuery("x");
assertThat((Query) query.unwrap(null)).isSameAs(targetQuery);
assertThat((Query) query.unwrap(targetQuery.getClass())).isSameAs(targetQuery);
assertThat(query.unwrap(Query.class)).isSameAs(query);
query.getResultList();
verify(query).getResultList(); verify(targetQuery).getResultList();
verify(targetEm).close(); verify(targetEm).close();
} }
@ -153,15 +168,20 @@ class SharedEntityManagerCreatorTests {
void deferredQueryWithResultStream() { void deferredQueryWithResultStream() {
EntityManagerFactory emf = mock(); EntityManagerFactory emf = mock();
EntityManager targetEm = mock(); EntityManager targetEm = mock();
Query query = mock(); Query targetQuery = mock();
given(emf.createEntityManager()).willReturn(targetEm); given(emf.createEntityManager()).willReturn(targetEm);
given(targetEm.createQuery("x")).willReturn(query); given(targetEm.createQuery("x")).willReturn(targetQuery);
given(targetEm.isOpen()).willReturn(true); given(targetEm.isOpen()).willReturn(true);
given((Query) targetQuery.unwrap(targetQuery.getClass())).willReturn(targetQuery);
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf); EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
em.createQuery("x").getResultStream(); Query query = em.createQuery("x");
assertThat((Query) query.unwrap(null)).isSameAs(targetQuery);
assertThat((Query) query.unwrap(targetQuery.getClass())).isSameAs(targetQuery);
assertThat(query.unwrap(Query.class)).isSameAs(query);
query.getResultStream();
verify(query).getResultStream(); verify(targetQuery).getResultStream();
verify(targetEm).close(); verify(targetEm).close();
} }
@ -169,11 +189,11 @@ class SharedEntityManagerCreatorTests {
void deferredStoredProcedureQueryWithIndexedParameters() { void deferredStoredProcedureQueryWithIndexedParameters() {
EntityManagerFactory emf = mock(); EntityManagerFactory emf = mock();
EntityManager targetEm = mock(); EntityManager targetEm = mock();
StoredProcedureQuery query = mock(); StoredProcedureQuery targetQuery = mock();
given(emf.createEntityManager()).willReturn(targetEm); given(emf.createEntityManager()).willReturn(targetEm);
given(targetEm.createStoredProcedureQuery("x")).willReturn(query); given(targetEm.createStoredProcedureQuery("x")).willReturn(targetQuery);
willReturn("y").given(query).getOutputParameterValue(0); willReturn("y").given(targetQuery).getOutputParameterValue(0);
willReturn("z").given(query).getOutputParameterValue(2); willReturn("z").given(targetQuery).getOutputParameterValue(2);
given(targetEm.isOpen()).willReturn(true); given(targetEm.isOpen()).willReturn(true);
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf); EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
@ -187,12 +207,12 @@ class SharedEntityManagerCreatorTests {
spq.getOutputParameterValue(1)); spq.getOutputParameterValue(1));
assertThat(spq.getOutputParameterValue(2)).isEqualTo("z"); assertThat(spq.getOutputParameterValue(2)).isEqualTo("z");
verify(query).registerStoredProcedureParameter(0, String.class, ParameterMode.OUT); verify(targetQuery).registerStoredProcedureParameter(0, String.class, ParameterMode.OUT);
verify(query).registerStoredProcedureParameter(1, Number.class, ParameterMode.IN); verify(targetQuery).registerStoredProcedureParameter(1, Number.class, ParameterMode.IN);
verify(query).registerStoredProcedureParameter(2, Object.class, ParameterMode.INOUT); verify(targetQuery).registerStoredProcedureParameter(2, Object.class, ParameterMode.INOUT);
verify(query).execute(); verify(targetQuery).execute();
verify(targetEm).close(); verify(targetEm).close();
verifyNoMoreInteractions(query); verifyNoMoreInteractions(targetQuery);
verifyNoMoreInteractions(targetEm); verifyNoMoreInteractions(targetEm);
} }
@ -200,11 +220,11 @@ class SharedEntityManagerCreatorTests {
void deferredStoredProcedureQueryWithNamedParameters() { void deferredStoredProcedureQueryWithNamedParameters() {
EntityManagerFactory emf = mock(); EntityManagerFactory emf = mock();
EntityManager targetEm = mock(); EntityManager targetEm = mock();
StoredProcedureQuery query = mock(); StoredProcedureQuery targetQuery = mock();
given(emf.createEntityManager()).willReturn(targetEm); given(emf.createEntityManager()).willReturn(targetEm);
given(targetEm.createStoredProcedureQuery("x")).willReturn(query); given(targetEm.createStoredProcedureQuery("x")).willReturn(targetQuery);
willReturn("y").given(query).getOutputParameterValue("a"); willReturn("y").given(targetQuery).getOutputParameterValue("a");
willReturn("z").given(query).getOutputParameterValue("c"); willReturn("z").given(targetQuery).getOutputParameterValue("c");
given(targetEm.isOpen()).willReturn(true); given(targetEm.isOpen()).willReturn(true);
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf); EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
@ -218,12 +238,12 @@ class SharedEntityManagerCreatorTests {
spq.getOutputParameterValue("b")); spq.getOutputParameterValue("b"));
assertThat(spq.getOutputParameterValue("c")).isEqualTo("z"); assertThat(spq.getOutputParameterValue("c")).isEqualTo("z");
verify(query).registerStoredProcedureParameter("a", String.class, ParameterMode.OUT); verify(targetQuery).registerStoredProcedureParameter("a", String.class, ParameterMode.OUT);
verify(query).registerStoredProcedureParameter("b", Number.class, ParameterMode.IN); verify(targetQuery).registerStoredProcedureParameter("b", Number.class, ParameterMode.IN);
verify(query).registerStoredProcedureParameter("c", Object.class, ParameterMode.INOUT); verify(targetQuery).registerStoredProcedureParameter("c", Object.class, ParameterMode.INOUT);
verify(query).execute(); verify(targetQuery).execute();
verify(targetEm).close(); verify(targetEm).close();
verifyNoMoreInteractions(query); verifyNoMoreInteractions(targetQuery);
verifyNoMoreInteractions(targetEm); verifyNoMoreInteractions(targetEm);
} }

2
spring-web/src/main/java/org/springframework/web/client/NoOpResponseErrorHandler.java

@ -36,7 +36,7 @@ public final class NoOpResponseErrorHandler implements ResponseErrorHandler {
@Override @Override
public void handleError(ClientHttpResponse response) throws IOException { public void handleError(ClientHttpResponse response) throws IOException {
// never actually called
} }
} }

3
spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2023 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -481,7 +481,6 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
@Override @Override
public void sendRedirect(String location) throws IOException { public void sendRedirect(String location) throws IOException {
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(location); UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(location);
UriComponents uriComponents = builder.build(); UriComponents uriComponents = builder.build();

Loading…
Cancel
Save