Merge branch '6.1.x'

This commit is contained in:
Juergen Hoeller 2024-10-29 23:04:05 +01:00
commit a1f6098158
6 changed files with 71 additions and 13 deletions

View File

@ -23,6 +23,12 @@ The following table lists all currently supported Spring properties.
|===
| Name | Description
| `spring.aop.ajc.ignore`
| Instructs Spring to ignore ajc-compiled aspects for Spring AOP proxying, restoring traditional
Spring behavior for scenarios where both weaving and AspectJ auto-proxying are enabled. See
{spring-framework-api}++/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.html#IGNORE_AJC_PROPERTY_NAME++[`AbstractAspectJAdvisorFactory`]
for details.
| `spring.aot.enabled`
| Indicates the application should run with AOT generated artifacts. See
xref:core/aot.adoc[Ahead of Time Optimizations] and
@ -32,7 +38,7 @@ for details.
| `spring.beaninfo.ignore`
| Instructs Spring to use the `Introspector.IGNORE_ALL_BEANINFO` mode when calling the
JavaBeans `Introspector`. See
{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`CachedIntrospectionResults`]
{spring-framework-api}++/beans/StandardBeanInfoFactory.html#IGNORE_BEANINFO_PROPERTY_NAME++[`StandardBeanInfoFactory`]
for details.
| `spring.cache.reactivestreams.ignore`
@ -49,15 +55,13 @@ for details.
| `spring.context.checkpoint`
| Property that specifies a common context checkpoint. See
xref:integration/checkpoint-restore.adoc#_automatic_checkpointrestore_at_startup[Automatic
checkpoint/restore at startup] and
xref:integration/checkpoint-restore.adoc#_automatic_checkpointrestore_at_startup[Automatic checkpoint/restore at startup] and
{spring-framework-api}++/context/support/DefaultLifecycleProcessor.html#CHECKPOINT_PROPERTY_NAME++[`DefaultLifecycleProcessor`]
for details.
| `spring.context.exit`
| Property for terminating the JVM when the context reaches a specific phase. See
xref:integration/checkpoint-restore.adoc#_automatic_checkpointrestore_at_startup[Automatic
checkpoint/restore at startup] and
xref:integration/checkpoint-restore.adoc#_automatic_checkpointrestore_at_startup[Automatic checkpoint/restore at startup] and
{spring-framework-api}++/context/support/DefaultLifecycleProcessor.html#EXIT_PROPERTY_NAME++[`DefaultLifecycleProcessor`]
for details.

View File

@ -100,8 +100,8 @@ dependencies {
api("org.apache.derby:derby:10.16.1.1")
api("org.apache.derby:derbyclient:10.16.1.1")
api("org.apache.derby:derbytools:10.16.1.1")
api("org.apache.httpcomponents.client5:httpclient5:5.4")
api("org.apache.httpcomponents.core5:httpcore5-reactive:5.3")
api("org.apache.httpcomponents.client5:httpclient5:5.4.1")
api("org.apache.httpcomponents.core5:httpcore5-reactive:5.3.1")
api("org.apache.poi:poi-ooxml:5.2.5")
api("org.apache.tomcat.embed:tomcat-embed-core:10.1.28")
api("org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28")

View File

@ -18,6 +18,7 @@ package org.springframework.aop.aspectj.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.StringTokenizer;
@ -37,6 +38,7 @@ import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.SpringProperties;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
@ -58,6 +60,23 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
private static final String AJC_MAGIC = "ajc$";
/**
* System property that instructs Spring to ignore ajc-compiled aspects
* for Spring AOP proxying, restoring traditional Spring behavior for
* scenarios where both weaving and AspectJ auto-proxying are enabled.
* <p>The default is "false". Consider switching this to "true" if you
* encounter double execution of your aspects in a given build setup.
* Note that we recommend restructuring your AspectJ configuration to
* avoid such double exposure of an AspectJ aspect to begin with.
* @since 6.1.15
*/
public static final String IGNORE_AJC_PROPERTY_NAME = "spring.aop.ajc.ignore";
private static final boolean shouldIgnoreAjcCompiledAspects =
SpringProperties.getFlag(IGNORE_AJC_PROPERTY_NAME);
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
@ -67,7 +86,8 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
@Override
public boolean isAspect(Class<?> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null &&
(!shouldIgnoreAjcCompiledAspects || !compiledByAjc(clazz)));
}
@Override
@ -114,6 +134,16 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
}
}
private static boolean compiledByAjc(Class<?> clazz) {
for (Field field : clazz.getDeclaredFields()) {
System.out.println(clazz + ": " + field.getName());
if (field.getName().startsWith(AJC_MAGIC)) {
return true;
}
}
return false;
}
/**
* Enum for AspectJ annotation types.

View File

@ -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");
* you may not use this file except in compliance with the License.
@ -303,6 +303,17 @@ public class CaffeineCacheManager implements CacheManager {
this.cacheMap.put(name, adaptCaffeineCache(name, cache));
}
/**
* Remove the specified cache from this cache manager, applying to
* custom caches as well as dynamically registered caches at runtime.
* @param name the name of the cache
* @since 6.1.15
*/
public void removeCache(String name) {
this.customCacheNames.remove(name);
this.cacheMap.remove(name);
}
/**
* Adapt the given new native Caffeine Cache instance to Spring's {@link Cache}
* abstraction for the specified cache name.

View File

@ -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");
* you may not use this file except in compliance with the License.
@ -175,6 +175,15 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA
return cache;
}
/**
* Remove the specified cache from this cache manager.
* @param name the name of the cache
* @since 6.1.15
*/
public void removeCache(String name) {
this.cacheMap.remove(name);
}
private void recreateCaches() {
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
entry.setValue(createConcurrentMapCache(entry.getKey()));

View File

@ -237,7 +237,7 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest
@Override
@SuppressWarnings("deprecation")
@SuppressWarnings("deprecation") // HttpClientContext.REQUEST_CONFIG
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
HttpClient client = getHttpClient();
@ -249,9 +249,10 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest
}
// Request configuration not set in the context
if (context.getAttribute(HttpClientContext.REQUEST_CONFIG) == null) {
// Use request configuration given by the user, when available
if (!(context instanceof HttpClientContext clientContext && clientContext.getRequestConfig() != null) &&
context.getAttribute(HttpClientContext.REQUEST_CONFIG) == null) {
RequestConfig config = null;
// Use request configuration given by the user, when available
if (httpRequest instanceof Configurable configurable) {
config = configurable.getConfig();
}
@ -259,6 +260,9 @@ public class HttpComponentsClientHttpRequestFactory implements ClientHttpRequest
config = createRequestConfig(client);
}
if (config != null) {
if (context instanceof HttpClientContext clientContext) {
clientContext.setRequestConfig(config);
}
context.setAttribute(HttpClientContext.REQUEST_CONFIG, config);
}
}