diff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc index eb046cc275..896453d8e9 100644 --- a/framework-docs/modules/ROOT/pages/appendix.adoc +++ b/framework-docs/modules/ROOT/pages/appendix.adoc @@ -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. diff --git a/framework-platform/framework-platform.gradle b/framework-platform/framework-platform.gradle index d2465d5b22..afe9512db1 100644 --- a/framework-platform/framework-platform.gradle +++ b/framework-platform/framework-platform.gradle @@ -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") diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java index 6f0eef8207..118d232545 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java @@ -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. + *
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.
diff --git a/spring-context-support/src/main/java/org/springframework/cache/caffeine/CaffeineCacheManager.java b/spring-context-support/src/main/java/org/springframework/cache/caffeine/CaffeineCacheManager.java
index 2518f3a57a..2ad316114b 100644
--- a/spring-context-support/src/main/java/org/springframework/cache/caffeine/CaffeineCacheManager.java
+++ b/spring-context-support/src/main/java/org/springframework/cache/caffeine/CaffeineCacheManager.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");
* 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.
diff --git a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java
index 585d8b2059..6dfa5a4eda 100644
--- a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java
+++ b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.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");
* 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